コンパウンド SQL (インライン) ステートメント

コンパウンド SQL (インライン化) ステートメントは、実行時に別の SQL ステートメント内でインライン化されるコンパウンド SQL ステートメントです。 コンパウンド SQL (インライン化) ステートメントには、アトミックに実行されるプロパティーが保持されており、ステートメントのいずれかの実行でエラーが発生すると、このステートメント全体がロールバックされます。

呼び出し

このステートメントはトリガー、SQL 関数、または SQL メソッドに組み込んだり、動的 SQL ステートメントを使用して発行したりすることができます。 このステートメントは、動的に作成できる実行可能ステートメントです。

許可

ステートメントの許可 ID によって保持される特権には、コンパウンド・ステートメントに指定されている SQL ステートメントを呼び出すために必要なすべての特権も含まれていなければなりません。

構文

Read syntax diagramSkip visual syntax diagramlabel:1BEGIN ATOMICSQL-variable-declarationcondition-declaration;,SQL-statement;END label
SQL-variable-declaration
Read syntax diagramSkip visual syntax diagramDECLARE,SQL-variable-namedata-typeDEFAULT NULLDEFAULTconstant
condition-declaration
Read syntax diagramSkip visual syntax diagramDECLAREcondition-nameCONDITION FOR SQLSTATEVALUE string-constant
SQL-statement
Read syntax diagramSkip visual syntax diagramCALLFORWITH,common-table-expressionfullselectGET DIAGNOSTICSIFINSERTITERATELEAVEMERGE RETURNsearched-deletesearched-updateSET VariableSIGNALWHILE
Notes:
  • 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 変数
  • パラメーター名
SQL 変数および列参照と同じ名前の ID が SQL ステートメントに含まれている場合、 その ID は列と解釈されます。
data-type
変数のデータ・タイプを指定します。 トリガーまたはメソッド内で使用される、あるいはスタンドアロン・ステートメントとして使用されるコンパウンド SQL (インライン化) ステートメント内では、XML データ・タイプはサポートされません (SQLSTATE 429BB)。 コンパウンド SQL (インライン化) ステートメントが SQL 関数本体で使用される場合、XML データ・タイプはサポートされます。
DEFAULT
SQL 変数のデフォルトを定義します。 コンパウンド SQL (インライン化) ステートメントが実行されると、この変数は初期化されます。 デフォルト値は、その変数のデータ・タイプと割り当てに互換性があるものでなければなりません。 デフォルト値が指定されていない場合、SQL 変数のデフォルトは初期化されて NULL 値になります。
ヌル
SQL 変数のデフォルト値として NULL を指定します。
constant
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-statementfullselect、または subselectisolation-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 という表が作成されます。
次に、[0..1000] の範囲外にあるすべての値を取り除き、 それらの値を 10 のステップに整列させることによってデータをクレンジングするための、 DISCRETIZE という名前の関数が作成されます。
   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