sap-sqlscript について
SAP HANA 開発者向けの SQLScript スキルで、プロシージャ、AMDP、パフォーマンス上の指針を扱います。構文やトラブルシューティング、最適化の資料を備え、データベース内での処理に役立ちます。
主な機能
- 01匿名ブロック、プロシージャ、関数
- 02変数、カーソル、例外処理
- 03AMDP 連携のガイド
- 04宣言型 SQL の性能指針
- 05構文・トラブルシューティング資料
活用シーン
- 01HANA のプロシージャや関数の作成
- 02AMDP でのデータベース処理の実装
- 03SQLScript 例外の調査
- 04データ量の多いクエリの最適化
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ secondsky/ sap-skills --skill sap-sqlscriptインストール後、Claude Code で/sap-sqlscriptを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdagents/openai.yamlreferences/advanced-features.mdamdp-integration.mdbuilt-in-functions.mddata-types.mdedge-cdp-control.mdexception-handling.mdglossary.mdperformance-guide.mdskill-reference-guide.mdsyntax-reference.mdtroubleshooting.mdtemplates/amdp-class.abapamdp-procedure.sqlbulk-operations.sqlcursor-iteration.sqlprocedure-with-error-handling.sqlscalar-function.sqlsimple-procedure.sqltable-function.sql詳細
SAP SQLScript 開発ガイド
このスキルを使用する場面
SQLScript のプロシージャ、匿名ブロック、テーブル関数/スカラー関数、AMDP メソッド、例外ハンドラー、カーソルロジック、一括操作、またはデータの近くで実行する必要がある HANA のパフォーマンス重視のデータベースロジックを記述する場合に、このスキルを使用します。
ブラウザベースの Datasphere または HANA Cloud SQL エディターのトリアージには、手動でのアプリ内認証、同意が必要な Edge プロファイルの再利用、新しい Edge/CDP の起動、認証状態の初期化、復旧に sap-browser-automation を使用します。SQLScript 固有の境界については、ローカルの references/edge-cdp-control.md を読み込みます。CDP はローカルの UI 確認、コンソール診断、デプロイメッセージ、承認済みのスクリーンショットにのみ使用します。データベースの検証は、引き続き SQL/HANA ツールで行うのが基本です。
概要
SQLScript は SAP HANA の SQL に対する手続き型拡張機能であり、複雑なデータ集約型ロジックをデータベース層で直接実行できます。コードをデータのある場所に移動するパラダイムに従い、データをアプリケーション層へ移動するのではなく、データが存在する場所で計算を行います。
主な特徴
- 大文字と小文字を区別しない言語
- すべての文はセミコロンで終わります
- 変数を参照するときはコロンを前置します(
:variableName) - 値を代入するときはコロンを付けません
- 単一行の操作には
DUMMYテーブルを使用します
2 種類のロジック
| 種類 | 説明 | 実行 |
|---|---|---|
| 宣言型 | 純粋な SQL シーケンス | データフローグラフに変換され、並列処理されます |
| 命令型 | 制御構造(IF、WHILE、FOR) | 順次処理され、並列実行を妨げます |
目次
- 概要
- コンテナの種類
- データ型
- 変数宣言
- 制御構造
- テーブル型
- カーソル
- 例外処理
- AMDP との統合
- パフォーマンスに関するベストプラクティス
- システム制限
- デバッグツール
- クイックリファレンス
- その他のリソース
コンテナの種類
1. 匿名ブロック
データベースに保存されない、1 回限りのロジックです。テストやアドホックな実行に便利です。
DO [(<parameter_clause>)]
BEGIN [SEQUENTIAL EXECUTION]
<body>
END;
例:
DO
BEGIN
DECLARE lv_count INTEGER;
SELECT COUNT(*) INTO lv_count FROM "MYTABLE";
SELECT :lv_count AS record_count FROM DUMMY;
END;
2. ストアドプロシージャ
入力/出力パラメーターを持つ、再利用可能なデータベースオブジェクトです。
CREATE [OR REPLACE] PROCEDURE <procedure_name>
(
[IN <param> <datatype>],
[OUT <param> <datatype>],
[INOUT <param> <datatype>]
)
LANGUAGE SQLSCRIPT
[SQL SECURITY {DEFINER | INVOKER}]
[DEFAULT SCHEMA <schema_name>]
[READS SQL DATA | READS SQL DATA WITH RESULT VIEW <view_name>]
AS
BEGIN
<procedure_body>
END;
3. ユーザー定義関数
スカラー UDF - 単一の値を返します:
CREATE FUNCTION <function_name> (<input_parameters>)
RETURNS <scalar_type>
LANGUAGE SQLSCRIPT
AS
BEGIN
<function_body>
RETURN <value>;
END;
テーブル UDF - テーブルを返します(読み取り専用):
CREATE FUNCTION <function_name> (<input_parameters>)
RETURNS TABLE (<column_definitions>)
LANGUAGE SQLSCRIPT
READS SQL DATA
AS
BEGIN
RETURN SELECT ... FROM ...;
END;
データ型
SQLScript は、さまざまな用途に対応する包括的なデータ型をサポートしています。以下を含む詳細なドキュメントについては、references/data-types.md を参照してください。
- 数値型(TINYINT、INTEGER、DECIMAL など)
- 文字型(VARCHAR、NVARCHAR、CLOB など)
- 日付/時刻型(DATE、TIME、TIMESTAMP、SECONDDATE)
- バイナリ型(VARBINARY、BLOB)
- 型変換関数(CAST、TO_ 関数)
- NULL の処理パターン
変数宣言
スカラー変数
DECLARE <variable_name> <datatype> [:= <initial_value>];
-- Examples
DECLARE lv_name NVARCHAR(100);
DECLARE lv_count INTEGER := 0;
DECLARE lv_date DATE := CURRENT_DATE;
注: 初期化されていない変数のデフォルト値は NULL です。
テーブル変数
暗黙的な宣言:
lt_result = SELECT * FROM "MYTABLE" WHERE status = 'A';
明示的な宣言:
DECLARE lt_data TABLE (
id INTEGER,
name NVARCHAR(100),
amount DECIMAL(15,2)
);
TABLE LIKE の使用:
DECLARE lt_copy TABLE LIKE :lt_original;
配列
DECLARE arr INTEGER ARRAY := ARRAY(1, 2, 3, 4, 5);
-- Access: arr[1], arr[2], etc. (1-based index)
-- Note: Arrays cannot be returned from procedures
制御構造
IF-ELSE 文
IF <condition1> THEN
<statements>
[ELSEIF <condition2> THEN
<statements>]
[ELSE
<statements>]
END IF;
比較演算子:
| 演算子 | 意味 |
|---|---|
= | 等しい |
> | より大きい |
< | より小さい |
>= | 以上 |
<= | 以下 |
!=, <> | 等しくない |
重要: IF-ELSE は SELECT 文の中では使用できません。代わりに CASE WHEN を使用してください。
WHILE ループ
WHILE <condition> DO
<statements>
END WHILE;
FOR ループ
-- Numeric range
FOR i IN 1..10 DO
<statements>
END FOR;
-- Reverse
FOR i IN REVERSE 10..1 DO
<statements>
END FOR;
-- Cursor iteration
FOR row AS <cursor_name> DO
<statements using row.column_name>
END FOR;
EXIT を使用する LOOP
LOOP
<statements>
IF <condition> THEN
BREAK;
END IF;
END LOOP;
テーブル型
再利用可能なテーブル構造を定義します:
CREATE TYPE <type_name> AS TABLE (
<column1> <datatype>,
<column2> <datatype>,
...
);
プロシージャでの使用:
CREATE PROCEDURE get_employees (OUT et_result MY_TABLE_TYPE)
LANGUAGE SQLSCRIPT AS
BEGIN
et_result = SELECT * FROM "EMPLOYEES";
END;
カーソル
カーソルは結果セットを行ごとに処理します。パターン:宣言 → オープン → フェッチ → クローズ
パフォーマンスに関する注意: カーソルはデータベースオプティマイザーを介さず、行を順番に処理します。主に主キーに基づくクエリで使用してください。可能な場合は、セットベースの操作を優先してください。
DECLARE CURSOR <cursor_name> FOR
SELECT <columns> FROM <table> [WHERE <condition>];
OPEN <cursor_name>;
FETCH <cursor_name> INTO <variables>;
CLOSE <cursor_name>;
完全な例:
DO
BEGIN
DECLARE lv_id INTEGER;
DECLARE lv_name NVARCHAR(100);
DECLARE CURSOR cur_employees FOR
SELECT id, name FROM "EMPLOYEES" WHERE dept = 'IT';
OPEN cur_employees;
FETCH cur_employees INTO lv_id, lv_name;
WHILE NOT cur_employees::NOTFOUND DO
-- Process row
SELECT :lv_id, :lv_name FROM DUMMY;
FETCH cur_employees INTO lv_id, lv_name;
END WHILE;
CLOSE cur_employees;
END;
FOR ループを使う方法:
FOR row AS cur_employees DO
SELECT row.id, row.name FROM DUMMY;
END FOR;
例外処理
EXIT HANDLER
例外が発生したときに実行を中断し、クリーンアップを実行します。
DECLARE EXIT HANDLER FOR <condition_value>
<statement>;
条件値:
SQLEXCEPTION- あらゆる SQL 例外SQL_ERROR_CODE <number>- 特定のエラーコード
エラー詳細へのアクセス:
::SQL_ERROR_CODE- 数値のエラーコード::SQL_ERROR_MESSAGE- エラーメッセージのテキスト
例:
CREATE PROCEDURE safe_insert (IN iv_id INTEGER, IN iv_name NVARCHAR(100))
LANGUAGE SQLSCRIPT AS
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SELECT ::SQL_ERROR_CODE AS err_code,
::SQL_ERROR_MESSAGE AS err_msg FROM DUMMY;
END;
INSERT INTO "MYTABLE" VALUES (:iv_id, :iv_name);
END;
CONDITION
ユーザー定義の名前をエラーコードに関連付けます:
DECLARE <condition_name> CONDITION FOR SQL_ERROR_CODE <number>;
-- Example
DECLARE duplicate_key CONDITION FOR SQL_ERROR_CODE 301;
DECLARE EXIT HANDLER FOR duplicate_key
SELECT 'Duplicate key error' FROM DUMMY;
SIGNAL と RESIGNAL
ユーザー定義の例外をスローします(コード 10000-19999):
-- Throw exception
SIGNAL <condition_name> SET MESSAGE_TEXT = '<message>';
-- Re-throw in handler
RESIGNAL [<condition_name>] [SET MESSAGE_TEXT = '<message>'];
一般的なエラーコード:
| コード | 説明 |
|---|---|
| 301 | 一意性制約違反 |
| 1299 | データが見つかりません |
AMDP 統合
ABAP Managed Database Procedures を使用すると、ABAP クラス内で SQLScript を利用できます。
クラス定義
CLASS zcl_my_amdp DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb. " Required interface
TYPES: BEGIN OF ty_result,
id TYPE i,
name TYPE string,
END OF ty_result,
tt_result TYPE STANDARD TABLE OF ty_result.
CLASS-METHODS: get_data
IMPORTING VALUE(iv_filter) TYPE string
EXPORTING VALUE(et_result) TYPE tt_result.
ENDCLASS.
メソッドの実装
CLASS zcl_my_amdp IMPLEMENTATION.
METHOD get_data BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING ztable.
et_result = SELECT id, name
FROM ztable
WHERE category = :iv_filter;
ENDMETHOD.
ENDCLASS.
AMDP の制限事項
- パラメーターは値渡しである必要があります(RETURNING は不可)
- 使用できるのはスカラー型、構造体、内部テーブルのみです
- 入れ子のテーブルやディープ構造は使用できません
- COMMIT/ROLLBACK は許可されていません
- 開発には Eclipse ADT を使用する必要があります
- 初回呼び出し時に自動作成されます
パフォーマンスに関するベストプラクティス
1. 早い段階でデータ量を減らす
-- Good: Filter and project early
lt_filtered = SELECT col1, col2 FROM "BIGTABLE" WHERE status = 'A';
lt_result = SELECT a.col1, b.name
FROM :lt_filtered AS a
JOIN "LOOKUP" AS b ON a.id = b.id;
-- Bad: Join then filter
lt_result = SELECT a.col1, b.name
FROM "BIGTABLE" AS a
JOIN "LOOKUP" AS b ON a.id = b.id
WHERE a.status = 'A';
2. 命令型より宣言型を優先する
-- Good: Set-based operation
lt_result = SELECT id, amount * 1.1 AS new_amount FROM "ORDERS";
-- Bad: Row-by-row processing
FOR row AS cur_orders DO
UPDATE "ORDERS" SET amount = row.amount * 1.1 WHERE id = row.id;
END FOR;
3. エンジンの混在を避ける
- 同じクエリ内で Row Store と Column Store のテーブルを混在させないでください
- 純粋な SQL で Calculation Engine 関数を使用しないでください
- ストレージの種類を統一してください
4. UNION の代わりに UNION ALL を使用する
-- Faster when duplicates impossible or acceptable
SELECT * FROM table1 UNION ALL SELECT * FROM table2;
-- Slower: removes duplicates
SELECT * FROM table1 UNION SELECT * FROM table2;
5. 動的 SQL を避ける
-- Bad: Re-optimized each execution
EXECUTE IMMEDIATE 'SELECT * FROM ' || :lv_table;
-- Good: Static SQL with parameters
SELECT * FROM "MYTABLE" WHERE id = :lv_id;
6. 命令型ロジックを最後に配置する
宣言型ステートメントの並列処理を最大限に活用するため、制御構造はプロシージャの最後に配置してください。
システムの制限
| 制限 | 値 |
|---|---|
| トランザクションあたりのテーブルロック数 | 16,383 |
| 1 つのステートメント内のテーブル数 | 4,095 |
| SQL ステートメントの長さ | 2 GB |
| プロシージャのサイズ | SQL ステートメントの長さで制限(2 GB) |
注: 実際の制限は HANA のバージョンによって異なる場合があります。バージョン固有の制限については SAP のドキュメントを参照してください。
デバッグツール
- SQLScript デバッガー - SAP Web IDE / Business Application Studio
- Plan Visualizer - 実行計画を分析します
- Expensive Statement Trace - ボトルネックを特定します
- SQL Analyzer - クエリ最適化に関する推奨事項を提示します
クイックリファレンス
文字列の連結
lv_result = lv_str1 || ' ' || lv_str2;
NULL の処理
COALESCE(value, default_value)
IFNULL(value, default_value)
NULLIF(value1, value2)
日付操作
ADD_DAYS(date, n)
ADD_MONTHS(date, n)
DAYS_BETWEEN(date1, date2)
CURRENT_DATE
CURRENT_TIMESTAMP
型変換
CAST(value AS datatype)
TO_VARCHAR(value)
TO_INTEGER(value)
TO_DATE(string, 'YYYY-MM-DD')
TO_TIMESTAMP(string, 'YYYY-MM-DD HH24:MI:SS')
関連スキル
SAP 開発を包括的に行うには、このスキルを以下と組み合わせてください:
| スキル | 使用例 |
|---|---|
| sap-abap | AMDP のコンテキストにおける ABAP プログラミングパターン |
| sap-abap-cds | SQLScript プロシージャを利用する CDS ビュー |
| sap-cap-capire | CAP フレームワークのデータベースプロシージャ統合 |
| sap-hana-cli | プロシージャのデプロイとテストに使用する HANA CLI |
| sap-btp-cloud-platform | HANA アーティファクトの BTP デプロイ |
同梱リソース
リファレンスドキュメント
references/skill-reference-guide.md- クイックナビゲーション付きの全リファレンス一覧references/glossary.md- SQLScript の用語と概念references/syntax-reference.md- SQLScript の完全な構文リファレンスreferences/built-in-functions.md- 組み込み関数のカタログreferences/data-types.md- データ型と変換references/exception-handling.md- 例外処理のパターンreferences/amdp-integration.md- AMDP 統合のパターンreferences/performance-guide.md- 最適化手法references/advanced-features.md- ラテラル結合、JSON、クエリヒント、通貨換算references/troubleshooting.md- よくあるエラーと解決策references/edge-cdp-control.md- 共有のsap-browser-automationEdge/CDP および認証レイヤー向けの SQLScript 固有のアドオン
本番環境ですぐに使えるテンプレート
一般的なパターンには、以下のテンプレートをコピーしてカスタマイズしてください。
templates/simple-procedure.sql- エラー処理を備えた基本的なストアドプロシージャtemplates/procedure-with-error-handling.sql- 包括的なエラー処理パターンtemplates/table-function.sql- 検証機能を備えたテーブル UDFtemplates/scalar-function.sql- スカラー UDF の例templates/amdp-class.abap- AMDP クラスの完全なボイラープレートtemplates/amdp-procedure.sql- AMDP 実装テンプレートtemplates/cursor-iteration.sql- カーソルのパターン(従来型と FOR ループ)templates/bulk-operations.sql- 高性能な一括操作
専門エージェント
- sqlscript-analyzer - パフォーマンスの問題とベストプラクティスに照らしてコードを分析します
- procedure-generator - 要件から対話的にプロシージャを生成します
- amdp-helper - AMDP クラスの作成とデバッグを支援します
スラッシュコマンド
/sqlscript-validate- 自動修正機能を備えたコード検証/sqlscript-optimize- パフォーマンス分析と最適化の提案/sqlscript-convert- スタンドアロン形式と AMDP 形式の相互変換
検証フック
Write/Edit 操作時に、次のコード品質チェックを自動実行します。
- エラー処理の網羅性
- セキュリティ上の脆弱性
- パフォーマンスに関するアンチパターン
- 命名規則
- AMDP への準拠