SAP HANA Development
SAP HANA テーブル関数の作り方とSQLScript実装・運用の要点
SAP HANAのテーブル関数をSQLScriptで作成し、SQLから呼び出し、プロシージャや計算ビューと使い分ける方法を実務向けに解説します。入力パラメータ、戻り値、権限、性能、トラブルシューティングまで扱います。
SAP HANAのテーブル関数は、SQLScriptで複数行の結果を返す再利用可能なデータベースオブジェクトです。入力パラメータを受け取り、SELECT文のFROM句から呼び出せるため、複雑な抽出ロジックをSQLの一部として組み込みたい場面で利用します。単純なSQLでは表現しにくい処理をデータベース側に集約できることが利点です。
この記事では、SQLコンソールでの作成、呼び出し、プロシージャとの使い分け、計算ビューとの連携、権限と性能の確認方法を順に説明します。開発全体の構成を確認したい場合は、SAP HANA開発の概要も参照してください。
テーブル関数の役割
テーブル関数は、表形式の結果を返す関数です。入力値に応じて検索条件や集計条件を変えながら、複数の列と複数の行を返せます。呼び出し側では通常のデータソースに近い形で扱えるため、SQL文、ビュー、計算ビューから同じロジックを再利用できます。
テーブル関数に向いているのは、次のような処理です。
- 複数のテーブルを結合して業務用の結果セットを作る
- 入力された期間、組織、ステータスで検索結果を絞り込む
- 条件分岐や中間テーブル変数を含むSQLScript処理を一つのデータソースにまとめる
- 計算ビューから呼び出す再利用可能なデータ取得ロジックを作る
戻り値の列構成は関数定義で明示します。呼び出し側が期待する列名、データ型、順序を最初に整理しておくと、後続のビューやアプリケーションとの接続が安定します。
作成前に決める設計
実装前に、入力パラメータと戻り値をデータ契約として定義します。入力パラメータには検索に必要な値だけを含め、利用しない値や画面都合の値を追加しないことが重要です。
次の項目を設計書またはチケットに記録しておくと、レビューと障害調査が容易になります。
| 項目 | 確認内容 |
|---|---|
| 入力 | 名前、データ型、必須性、NULLの扱い |
| 出力 | 列名、データ型、意味、NULLの扱い |
| 粒度 | 1行が何を表すか |
| 期間条件 | タイムゾーン、開始日と終了日の境界 |
| 権限 | 実行者が参照するオブジェクトへの権限 |
| 性能 | 想定行数、同時実行数、許容応答時間 |
テーブル関数内部の処理は、同じ結果を返すだけの単純なSELECTから始めます。複雑な分岐や一時的な中間処理を追加する場合も、最終的な結果の粒度が変わらないかを確認します。
SQLScriptでテーブル関数を作る
SAP HANAデータベースエクスプローラーのSQLコンソール、またはSQLScriptを実行できる開発環境から作成できます。基本形は、入力パラメータ、RETURNS TABLE、LANGUAGE SQLSCRIPT、本体の順に記述します。
CREATE FUNCTION MY_SCHEMA.get_sales_summary (
iv_customer_id NVARCHAR(20),
iv_from_date DATE,
iv_to_date DATE
)
RETURNS TABLE (
customer_id NVARCHAR(20),
order_count INTEGER,
total_amount DECIMAL(15, 2)
)
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER
AS
BEGIN
RETURN
SELECT
customer_id,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM MY_SCHEMA.sales_data
WHERE customer_id = :iv_customer_id
AND order_date >= :iv_from_date
AND order_date < :iv_to_date
GROUP BY customer_id;
END;
SQLScript内で入力パラメータを参照するときは、上の例のようにコロンを付けます。日付の終了条件を次の日の直前として扱う設計では、終了日の境界を明確にできます。実際のテーブル名、列名、データ型は対象データモデルに合わせて置き換えます。
作成後は、構文エラーだけでなく、戻り値の型とSELECT結果の型が一致していることを確認します。集計結果の型が戻り値の定義より広い場合は、CASTで明示的に変換します。開発用スキーマと本番用スキーマを分ける場合は、依存オブジェクトの所有者も整理します。
テーブル関数を呼び出す
テーブル関数は、入力値を指定してFROM句から呼び出します。スキーマ名を含め、戻り値にエイリアスを付けて利用すると、結合や列参照が読みやすくなります。
SELECT
s.customer_id,
s.order_count,
s.total_amount
FROM MY_SCHEMA.get_sales_summary(
'C0001',
TO_DATE('2024-01-01'),
TO_DATE('2024-02-01')
) AS s;
別のテーブルと結合する場合も、テーブル関数をデータソースとして扱えます。ただし、関数の内部で大量の行を生成してから外側で絞り込む設計は、不要なデータ処理を増やします。可能な条件は入力パラメータとして関数内部に渡し、早い段階で絞り込む構造にします。
テーブル関数を計算ビューで使う場合は、入力パラメータのマッピング、出力列の型、データアクセス権限を一緒に確認します。計算ビューの実装パターンについては、SAP HANAの計算ビューを参照してください。
プロシージャとの使い分け
テーブル関数とプロシージャは、どちらもSQLScriptを使って複雑な処理を実装できますが、呼び出し方と用途が異なります。
| 観点 | テーブル関数 | プロシージャ |
|---|---|---|
| 主な呼び出し方 | SELECTのFROM句 | CALL文 |
| 結果 | 定義した表形式の戻り値 | 出力パラメータや結果セット |
| 用途 | 検索、変換、集計、データソース化 | 業務処理、複数段階の処理、更新を伴う処理 |
| 利用先 | SQL、ビュー、計算ビュー | アプリケーション、ジョブ、別のSQLScript処理 |
| 副作用 | 読み取り中心の処理 | 更新や複数操作を含む処理に適する |
検索結果を他のSQLに組み込みたい場合はテーブル関数を選び、明示的な処理フローや更新処理を実行したい場合はプロシージャを検討します。プロシージャの設計と呼び出しについては、SAP HANA SQLScriptプロシージャで関連する実装例を確認できます。
テーブル関数の中に更新処理や外部副作用を持つ処理を詰め込むと、SQLの読み手が処理結果を予測しにくくなります。読み取り用の関数と更新用のプロシージャを分離すると、権限設計と障害調査も単純になります。
権限と実行コンテキストを確認する
SQL SECURITY INVOKERを指定したテーブル関数では、呼び出し元の実行コンテキストでアクセス権限が評価されます。利用者またはアプリケーションのデータベースユーザーが、関数だけでなく内部で参照するテーブルやビューへアクセスできることを確認します。
権限エラーを調べるときは、次の順序で確認します。
- 関数が存在するスキーマと完全修飾名を確認する
- 実行ユーザーが関数を実行できる権限を確認する
- 関数内部の参照オブジェクトに対する権限を確認する
- シノニムやロール経由の権限が想定どおり有効か確認する
- SQLコンソールでアプリケーションと同じユーザーを使って再現する
開発者ユーザーでは実行できても、アプリケーションユーザーでは失敗するケースがあります。テストは実際の接続ユーザーと同じ権限構成で行います。
性能を確認する
テーブル関数の性能は、関数内部のSQLだけでなく、呼び出し側との組み合わせで決まります。最初に、入力条件が大きすぎないか、結合キーに適した条件があるか、不要な列を返していないかを確認します。
特に注意する項目は次のとおりです。
- 入力パラメータで期間や組織範囲を制限する
SELECT *を避け、必要な列だけを返す- 大量の中間結果を作る処理を分割して確認する
- 重複行が増える結合を特定する
- 集計前に不要な行を除外する
- 同じ関数を多重に呼び出すSQLを見直す
SAP HANAデータベースエクスプローラーで実行計画や実行時間を確認し、入力値を変えた場合の行数と処理時間を比較します。性能問題の切り分けでは、関数単体、関数を含むSELECT、アプリケーションからの実行を分けて計測します。SAP HANA開発の性能チューニングには、開発時に確認する観点をまとめています。
トラブルシューティング
作成や呼び出しで問題が発生した場合は、エラーメッセージの全文、実行ユーザー、入力値、関数のバージョンを記録します。入力値がNULL、空文字、境界日付のときにだけ発生する問題もあるため、正常系だけで判断しません。
構文エラー
RETURNS TABLEの列定義、本体のRETURN文、入力パラメータの参照方法を確認します。SELECTが返す列数と戻り値の列数、列の順序、データ型を照合します。
オブジェクトが見つからない
スキーマ名を含む完全修飾名で参照し、実行ユーザーから参照可能か確認します。開発環境で作成した関数が別スキーマに存在する場合は、呼び出し側のSQLも同じ名前空間を参照するようにします。
権限エラー
関数の実行権限と、内部で参照するテーブル・ビューへの権限を分けて確認します。ロールの付与先がユーザーか別ロールか、接続セッションに反映されているかも確認します。
結果が空になる
入力パラメータの型変換、日付の境界、NULL比較、結合条件を確認します。特にNULLは通常の等価比較では一致しないため、NULLを許容する仕様なら条件を明示します。
応答が遅い
同じ入力値で関数単体と呼び出し側SQLを比較します。実行計画、処理対象行数、結合順序、集計前のデータ量を確認し、関数内部で条件が適用されているかを調べます。
運用に移す手順
本番反映前に、関数定義、依存オブジェクト、権限、テストSQL、想定結果を一つの変更単位として管理します。戻り値の列名や型を変更すると、計算ビューやアプリケーション側に影響するため、互換性を確認してから反映します。
運用手順は次の流れにすると安全です。
- 開発スキーマで正常系、境界値、権限エラーをテストする
- 実行計画と代表的な応答時間を記録する
- 依存するテーブル、ビュー、ロールを一覧化する
- テスト用ユーザーとアプリケーションユーザーで結果を比較する
- 反映後に件数、NULL、集計値、応答時間を確認する
- 変更前の定義とロールバック手順を保存する
SQLScriptの再利用性を高めるには、関数を小さく保ち、入力と出力の意味を明確にします。データモデルやデプロイ方式を含めた開発設計は、対象システムの運用ルールに合わせて管理してください。