SAP HANA Development
SAP HANA SQLScriptプロシージャの書き方と実運用でのデバッグ手順
SAP HANAのSQLScriptプロシージャを作成する構文、入力・出力パラメータ、テーブル変数、権限、性能確認、エラー調査の実務手順をサンプル付きで解説します。
SAP HANAのSQLScriptプロシージャは、複数のSQL処理や条件分岐、テーブル操作をデータベース側でまとめて実行するためのデータベースオブジェクトです。アプリケーションから個別のSQLを何度も送る構成を減らし、処理単位を明確にできます。
この記事では、SAP HANAデータベースエクスプローラーやSAP HANA cockpitを使って、プロシージャの作成、呼び出し、権限確認、エラー調査、性能確認までを実際の運用に沿って整理します。最初に決めるべきなのは、入力値、返却する値、読み書きするオブジェクト、そして処理をデータベース側に置く理由です。
SQLScriptプロシージャの基本構造
SQLScriptプロシージャは、スキーマ名とプロシージャ名、パラメータ、実行ブロックで構成します。実行ブロックでは、SQL文とSQLScriptの代入、条件分岐、ループなどを組み合わせます。
CREATE OR REPLACE PROCEDURE DEV_APP.GET_ORDER_TOTALS
(
IN IV_CUSTOMER_ID INTEGER,
OUT OT_TOTALS TABLE
(
CUSTOMER_ID INTEGER,
ORDER_COUNT INTEGER,
TOTAL_AMOUNT DECIMAL(15, 2)
)
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER
AS
BEGIN
OT_TOTALS =
SELECT
CUSTOMER_ID,
COUNT(*) AS ORDER_COUNT,
SUM(AMOUNT) AS TOTAL_AMOUNT
FROM DEV_APP.ORDERS
WHERE CUSTOMER_ID = :IV_CUSTOMER_ID
GROUP BY CUSTOMER_ID;
END;
入力パラメータは IV_CUSTOMER_ID のように宣言し、SQL文の中ではコロンを付けて参照します。出力テーブルパラメータには返却する列名と型を定義します。CREATE OR REPLACE PROCEDURE を使うと、既存オブジェクトの定義を置き換えながら開発できます。
SQL SECURITY INVOKER は呼び出しユーザーの権限でオブジェクトへアクセスする設定です。アプリケーションの実行ユーザーに必要な権限を付与する構成では、この設定とロール設計を一緒に確認します。所有者権限で実行する設計では、アクセス範囲を十分に限定し、意図しないデータ参照を防ぎます。
入力と出力を設計する
プロシージャの使いやすさは、パラメータ設計で大きく変わります。入力値には業務上意味のある粒度を設定し、同じ呼び出しで再現できる結果を返す形にします。日付範囲を受け取る場合は、開始日と終了日を別のパラメータとして定義し、境界条件を処理の中で統一します。
CREATE OR REPLACE PROCEDURE DEV_APP.FIND_ORDERS
(
IN IV_DATE_FROM DATE,
IN IV_DATE_TO DATE,
IN IV_STATUS NVARCHAR(20),
OUT OT_ORDERS TABLE
(
ORDER_ID BIGINT,
ORDER_DATE DATE,
STATUS NVARCHAR(20),
AMOUNT DECIMAL(15, 2)
)
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER
AS
BEGIN
OT_ORDERS =
SELECT ORDER_ID, ORDER_DATE, STATUS, AMOUNT
FROM DEV_APP.ORDERS
WHERE ORDER_DATE >= :IV_DATE_FROM
AND ORDER_DATE < :IV_DATE_TO
AND STATUS = :IV_STATUS;
END;
終了日を次の日の00:00未満として扱うと、時刻を含むデータでも範囲条件を一貫させやすくなります。入力値がNULLになり得る場合は、NULLを「条件なし」と解釈するのか、入力エラーにするのかを決めてから条件式を記述します。
大量の行を返すプロシージャでは、出力テーブルの列を必要最小限にします。画面表示用、連携用、集計用の出力を一つに詰め込むと、転送量と後続処理が増えます。用途が異なる場合は、呼び出し側の責務を分けるか、別のプロシージャとして管理します。
プロシージャでは、入力パラメータのほかに、スカラー変数とテーブル変数を使用できます。テーブル変数には検索結果を代入し、その後の処理で再利用します。
lt_items =
SELECT ITEM_ID, QUANTITY, UNIT_PRICE
FROM DEV_APP.ORDER_ITEMS
WHERE ORDER_ID = :IV_ORDER_ID;
lt_totals =
SELECT
SUM(QUANTITY) AS TOTAL_QUANTITY,
SUM(QUANTITY * UNIT_PRICE) AS TOTAL_AMOUNT
FROM :lt_items;
テーブル変数を参照するときは、変数名の前にコロンを付けます。中間結果を必要以上に増やさず、同じデータを何度も読み直さない構造にすると、処理の意図と実行計画を確認しやすくなります。
プロシージャを実行する
作成したプロシージャは、SAP HANAデータベースエクスプローラーのSQLコンソールから呼び出せます。出力テーブルを確認したい場合は、匿名ブロックで出力変数を受け取る方法が扱いやすい構成です。
DO
BEGIN
DECLARE lt_result TABLE
(
CUSTOMER_ID INTEGER,
ORDER_COUNT INTEGER,
TOTAL_AMOUNT DECIMAL(15, 2)
);
CALL DEV_APP.GET_ORDER_TOTALS(10001, lt_result);
SELECT * FROM :lt_result;
END;
プロシージャのパラメータ定義を確認してから、入力値の型と順序を合わせます。アプリケーションから呼び出す場合は、使用するデータベース接続ユーザー、スキーマ、トランザクション境界、結果セットの取り扱いを接続方式に合わせます。
プロシージャ名をスキーマで修飾すると、接続ユーザーのデフォルトスキーマに依存しません。開発環境と本番環境でスキーマ名が異なる場合は、デプロイ設定で解決し、ソースコード内に環境固有の名前を広げないようにします。
関連する集計ロジックを計算ビューで再利用する場合は、SAP HANA計算ビューの作成方法も参照してください。プロシージャは命令的な処理や複数ステップの更新に向き、計算ビューは宣言的な分析モデルに向いています。
権限とSQL SECURITYを確認する
プロシージャの実行に必要な権限は、プロシージャ自体への実行権限と、参照・更新対象へのアクセス権限に分けて確認します。SQL SECURITY INVOKER では呼び出しユーザーの権限が評価されるため、アプリケーションロールから必要なオブジェクトへ到達できることを検証します。
GRANT EXECUTE ON PROCEDURE DEV_APP.GET_ORDER_TOTALS TO APP_RUNTIME;
対象テーブルを直接参照する設計では、対象オブジェクトへの権限も必要です。権限をロールへまとめ、個別ユーザーへ直接付与する数を抑えると、棚卸しと変更管理が容易になります。
入力値をSQL文字列へ連結して動的SQLを組み立てる場合は、許可するオブジェクト名や条件を明示的に制御します。利用者入力をそのままSQLへ連結せず、固定のSQLとパラメータで処理できる形を優先します。動的SQLが必要な場合は、実行主体とアクセス対象を限定し、監査ログで追跡できる状態にします。
性能を確認する
SQLScriptの性能問題は、プロシージャ全体を一度に判断せず、各SQL文の読み取り量、結合条件、集約、結果行数に分けて確認します。SQLコンソールで個別のSELECTを実行し、実行計画と処理時間を比較すると、ボトルネックを切り分けやすくなります。
大きなテーブルを対象にする処理では、早い段階で対象期間やキーによる絞り込みを行います。不要な列をSELECTに含めず、結合前にデータ量を減らします。行単位のループで同じテーブルを繰り返し読む構造は、集合演算へ置き換えられないかを最初に検討します。
SQLScriptの処理を改善するときは、SAP HANA開発の性能チューニング手順にある確認順序も役立ちます。メモリ使用量、実行時間、並列処理、データ量の変化を同じ条件で記録すると、変更の効果を判断できます。
計算ビューやテーブル関数と処理を分担する場合は、データの受け渡し箇所を明確にします。テーブル関数の設計を比較するときは、SAP HANAテーブル関数の使い方を確認し、読み取り専用の処理と更新を伴う処理を適切に分離します。
エラーを調査する
エラー調査では、まずSQLコンソールに表示されたエラーコード、メッセージ、発生した文を保存します。アプリケーション側で例外を一般化すると原因が見えなくなるため、サーバー側のメッセージとアプリケーションログの相関IDを結び付けます。
次に、同じ入力値で最小の呼び出しを実行します。入力パラメータ、対象スキーマ、現在のユーザー、対象テーブルの存在、権限、データ型を順番に確認します。列名やオブジェクト名の大文字・小文字を含め、作成時の定義と呼び出し側の記述を一致させます。
テーブル変数を使う処理では、各代入の後に行数や代表値を確認するSELECTを一時的に追加すると、空の中間結果を見つけやすくなります。確認後は診断用の出力を本番用コードへ残さず、ログへ出す情報にも機密データを含めないようにします。
プロシージャの定義を変更した後は、依存する計算ビュー、テーブル関数、アプリケーションの結果マッピングを再確認します。開発全体の構成や依存関係は、SAP HANA開発の全体像から関連する設計領域へたどれます。
運用へ移す前の確認
本番反映前には、正常系だけでなく、該当データが0件のケース、NULL入力、境界日付、重複データ、想定外のステータスを確認します。大量データでの処理時間と同時実行時の挙動も、代表的なデータ量で測定します。
変更管理では、プロシージャのDDL、依存オブジェクト、権限付与、テスト結果を同じ変更単位で記録します。CREATE OR REPLACE PROCEDURE による置換を使う場合も、現行定義を保存し、ロールバック可能な手順を用意します。
実行権限を付与したユーザーで呼び出しテストを行い、開発者権限だけで成功する状態を本番品質と判断しないことが重要です。対象テーブルの追加や列変更がある場合は、プロシージャの出力契約とアプリケーションのマッピングを再確認します。
まとめ
SAP HANA SQLScriptプロシージャは、入力・出力の契約を明確にし、集合演算を中心に組み立てると保守しやすくなります。権限、SQL SECURITY、スキーマ修飾、エラー情報、実行計画を一つの確認手順にまとめることで、開発環境から運用環境への移行も安定します。
最初に小さなプロシージャで入力値と結果を検証し、処理量が増えた段階で中間結果、結合、集約、権限を個別に確認します。用途が読み取り専用の分析なのか、複数ステップの更新なのかを整理して、計算ビューやテーブル関数との役割分担を決めることが実務上の重要な判断になります。