コンパウンド SQL (インライン) ステートメント
コンパウンド SQL (インライン化) ステートメントは、実行時に別の SQL ステートメント内でインライン化されるコンパウンド SQL ステートメントです。 コンパウンド SQL (インライン化) ステートメントには、アトミックに実行されるプロパティーが保持されており、ステートメントのいずれかの実行でエラーが発生すると、このステートメント全体がロールバックされます。
呼び出し
このステートメントはトリガー、SQL 関数、または SQL メソッドに組み込んだり、動的 SQL ステートメントを使用して発行したりすることができます。 このステートメントは、動的に作成できる実行可能ステートメントです。
許可
ステートメントの許可 ID によって保持される特権には、コンパウンド・ステートメントに指定されている SQL ステートメントを呼び出すために必要なすべての特権も含まれていなければなりません。
構文
- 1 A label can only be specified when the statement is in a function, method, or trigger definition.
説明
- label
- コード・ブロックのラベルを定義します。 開始ラベルを指定した場合、そのラベルを使用して、コンパウンド SQL (インライン化) ステートメントで宣言する SQL 変数を修飾することができます。また、開始ラベルは LEAVE ステートメントで指定することもできます。 終了ラベルを指定する場合、そのラベルは開始ラベルと同じでなければなりません。
- ATOMIC
- ATOMIC は、コンパウンド・ステートメントでエラーが起こった場合、
そのコンパウンド・ステートメント内の SQL ステートメントがすべてロールバックされ、
以降の SQL ステートメントは処理されないことを指示します。
モジュール内の SQL 関数または SQL プロシージャーに ATOMIC キーワードが指定されていると、コンパウンド・ステートメントはコンパウンド SQL (コンパイル済み) ステートメントとして処理されます。
- SQL-statement
- コンパウンド SQL (インライン化) ステートメント内で実行する SQL ステートメントを指定します。
- SQL-variable-declaration
- コンパウンド SQL (インライン化) ステートメントに対してローカルな変数を宣言します。
- SQL 変数名 (SQL-variable-name)
- ローカル変数の名前を定義します。 SQL 変数名は大文字に変換されます。 この名前を以下のものと同じにすることはできません。
- コンパウンド・ステートメント内の別の SQL 変数
- パラメーター名
data-type - 変数のデータ・タイプを指定します。 トリガーまたはメソッド内で使用される、あるいはスタンドアロン・ステートメントとして使用されるコンパウンド SQL (インライン化) ステートメント内では、XML データ・タイプはサポートされません (SQLSTATE 429BB)。 コンパウンド SQL (インライン化) ステートメントが SQL 関数本体で使用される場合、XML データ・タイプはサポートされます。
- DEFAULT
- SQL 変数のデフォルトを定義します。 コンパウンド SQL (インライン化) ステートメントが実行されると、この変数は初期化されます。 デフォルト値は、その変数のデータ・タイプと割り当てに互換性があるものでなければなりません。 デフォルト値が指定されていない場合、SQL 変数のデフォルトは初期化されて NULL 値になります。
- ヌル
- SQL 変数のデフォルト値として NULL を指定します。 constant
- SQL 変数のデフォルト値として定数を指定します。
- ローカル変数の名前を定義します。 SQL 変数名は大文字に変換されます。 この名前を以下のものと同じにすることはできません。
- condition-declaration
- 条件名および対応する SQLSTATE 値を宣言します。
- 条件名
- 条件の名前を指定します。 条件名は、それが宣言されるコンパウンド・ステートメント内で固有でなければなりません。ただし、そのようなコンパウンド・ステートメント内でネストされたコンパウンド・ステートメント内での宣言は除きます (SQLSTATE 42734)。 条件名は、それが宣言されたコンパウンド・ステートメント内でのみ参照が可能です。コンパウンド・ステートメント内でネストされたコンパウンド・ステートメントも同様です (SQLSTATE 42737)。
- FOR SQLSTATE string-定数
- 条件に関連する SQLSTATE を指定します。 string-constant は単一引用符で囲まれている 5 つの文字として指定しなければならず、SQLSTATE クラス (最初の 2 文字) は '00' にすることはできません。
注
- コンパウンド SQL (インライン化) ステートメントは、単一ステートメントとしてコンパイルされます。 このステートメントは、小さな制御フロー・ロジックを含む短いスクリプトに有効ですが、 大きな意味を持つデータ・フローには有効ではありません。 制御フローのネストまたは条件処理が必要な大きな構成の場合、コンパウンド SQL (コンパイル済み) ステートメントまたは SQL プロシージャーの使用をお勧めします。
- コンパウンド・ステートメント内で呼び出されるプロシージャーは、 COMMIT または ROLLBACK ステートメントを発行できません (SQLSTATE 42985)。
- 表アクセスの制限: プロシージャーが READS SQL DATA または MODIFIES SQL DATA として定義されている場合は、 プロシージャー内のステートメントは、 このプロシージャーを呼び出したコンパウンド・ステートメントによって変更される表にアクセスすることはできません (SQLSTATE 57053)。 プロシージャーが MODIFIES SQL DATA として定義されている場合は、プロシージャー内のステートメントは、 このプロシージャーを呼び出したコンパウンド・ステートメントによって読み取られるまたは変更される表を変更できません (SQLSTATE 57053)。
- XML 割り当て: データ・タイプ XML のパラメーターおよび変数に対する割り当ては、SQL 関数本体の参照によって行われます。
参照によって XML 値を渡すときには、入力ノード・ツリーが直接使用されます。 この直接的な使用により、文書の順序、元のノード ID、およびすべての親プロパティーを含むすべてのプロパティーが保持されます。
- 分離レベル: select-statement、fullselect、または subselect が isolation-clause を指定する場合は、この節は無視され、警告が戻されます。
例
この例では、データ・クレンジングを行うために、 データウェアハウジング・シナリオでインライン SQL PL を使用する方法を示します。
この例には、3 つの表があります。 TARGET 表には、クレンジングされたデータが入ります。 EXCEPT 表にはクレンジングできない行 (例外) が保管され、 SOURCE 表にはクレンジングするロー・データが入ります。
データを分類して変更するために、DISCRETIZE という単純な SQL 関数が使用されます。 これは、不良データの場合はすべて NULL 値を戻します。 次いで、コンパウンド SQL (インライン化) ステートメントがデータをクレンジングします。 このステートメントは、FOR ループで SOURCE 表の中のすべての行を処理し、 DISCRETIZE 関数の結果に従って、 現在行を TARGET 表と EXCEPT 表のどちらに挿入するのかを決定します。 この技法を使用して、より複雑なメカニズム (複数ステージのクレンジング) にすることができます。
SQL プロシージャー、その他の任意のプロシージャー、またはホスト言語のアプリケーションで、 同じコードを作成できます。 ただし、コンパウンド SQL (インライン化) ステートメントには独特の利点があります。つまり、FOR ループでカーソルが開くことはなく、単一行挿入も実際の単一行挿入ではありません。 実際には、共有選択からの複数表挿入という効果的な論理になっています。
これは、コンパウンド SQL (インライン化) ステートメントを単一ステートメントとしてコンパイルすることによって達成されます。 ビューを使用する照会に統合され、照会コンテキスト内で全体としてコンパイルおよび最適化される 本体を持つビューと同様に、データベース・オプティマイザーは、 制御フローとデータ・フローの両方をコンパイルおよび最適化します。 したがって、全体の論理は、データベースのランタイム環境内で実行されます。 プロシージャーの場合とは異なり、データベースのコア・エンジンの外部に移動されるデータはありません。
CREATE TABLE TARGET
(PK INTEGER NOT NULL
PRIMARY KEY, C1 INTEGER)
クレンジングされたデータを入れるための TARGET という表が作成されます。
CREATE TABLE EXCEPT
(PK INTEGER NOT NULL
PRIMARY KEY, C1 INTEGER)
例外を入れるための EXCEPT という表が作成されます。 CREATE TABLE SOURCE
(PK INTEGER NOT NULL
PRIMARY KEY, C1 INTEGER)
クレンジングするデータを保持する SOURCE という表が作成されます。 CREATE FUNCTION DISCRETIZE(RAW INTEGER) RETURNS INTEGER
RETURN CASE
WHEN RAW < 0 THEN CAST(NULL AS INTEGER)
WHEN RAW > 1000 THEN NULL
ELSE ((RAW / 10) * 10) + 5
END
INSERT INTO SOURCE (PK, C1)
VALUES (1, -5),
(2, NULL),
(3, 1200),
(4, 23),
(5, 10),
(6, 876)
BEGIN ATOMIC
FOR ROW AS
SELECT PK, C1, DISCRETIZE(C1) AS D FROM SOURCE
DO
IF ROW.D IS NULL THEN
INSERT INTO EXCEPT VALUES(ROW.PK, ROW.C1);
ELSE
INSERT INTO TARGET VALUES(ROW.PK, ROW.D);
END IF;
END FOR;
END
SELECT * FROM EXCEPT ORDER BY 1
PK C1
----------- -----------
1 -5
2 -
3 1200
3 record(s) selected.
SELECT * FROM TARGET ORDER BY 1
PK C1
----------- -----------
4 25
5 15
6 875
3 record(s) selected.
DROP FUNCTION DISCRETIZE
DROP TABLE SOURCE
DROP TABLE TARGET
DROP TABLE EXCEPT