インライン SQL 関数、トリガー、およびコンパウンド SQL ステートメント

インライン SQL PL ステートメントは、コンパウンド SQL (コンパイル済み) ステートメント、コンパウンド SQL (インライン化) ステートメント、SQL 関数、およびトリガーで実行することができます。

コンパウンド SQL (インライン化) ステートメントとは、複数の SQL ステートメントをオプションのアトミック・ブロックにまとめるためのステートメントであり、このブロックでは、変数や条件処理エレメントを宣言することができます。 この種のステートメントは、Db2® によって 1 つの SQL ステートメントとしてコンパイルされます。また、インライン SQL PL ステートメントを組み込むことも可能です。

SQL 関数およびトリガーの本体には、コンパウンド SQL (インライン化) ステートメントを収容することができ、また、一部のインライン SQL PL ステートメントを組み込むこともできます。

コンパウンド SQL (インライン化) ステートメントを単独で使用するのが便利なのは、最小限の制御フローで小単位のロジック作業を実行する一方で、そのデータ・フローはかなりの量になるような、短いスクリプトを作成する場合です。 関数およびトリガー内で、そのようなオブジェクトの使用時にさらに複雑なロジックを実行できるようになります。

SQL PL を使用したコンパウンド SQL (インライン化) ステートメントの例として、以下を考察してみます。
   BEGIN ATOMIC
     FOR row AS
       SELECT pk, c1, discretize(c1) AS v FROM source
     DO
       IF row.v 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
コンパウンド SQL (インライン化) ステートメントには、キーワード BEGIN および END がバインドされています。 その一環として、SQL PL の一部を成す FOR および IF/ELSE 制御ステートメントの両方が使用されています。FOR ステートメントは、一連の定義済みの行に対する反復処理で使用されます。 各行ごとに列の値が検査され、条件によっては、値に基づいて一連の値が別の表に挿入されます。
SQL PL を使用したトリガーの例として、以下を考察してみます。
  CREATE TRIGGER validate_sched
  NO CASCADE BEFORE INSERT ON c1_sched
  FOR EACH ROW
  MODE Db2SQL
  Vs: BEGIN ATOMIC

    IF (n.ending IS NULL) THEN
      SET n.ending = n.starting + 1 HOUR;
    END IF;

    IF (n.ending > '21:00') THEN
      SIGNAL SQLSTATE '80000'  SET MESSAGE_TEXT = 
             'Class ending time is after 9 PM';
    ELSE IF (n.DAY=1 or n.DAY-7) THEN
      SIGNAL SQLSTATE '80001' SET MESSAGE_TEXT = 
             'Class cannot be scheduled on a weekend';
    END IF;
  END vs;
このトリガーは、c1_sched という名前の表への挿入と同時に活動化してから、SQL PL を使用して、クラスの終了時刻を検査し、未指定の場合はその時刻を設定し、クラスの終了時刻が午後 9 時より遅い場合や、クラスが週末にスケジュールされている場合は、エラーを生じます。 SQL PL を使用したスカラー SQL 関数の例として、以下を考察してみます。

  CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)  
  RETURNS  DECIMAL(10,3) 
  LANGUAGE SQL  MODIFIES SQL
  BEGIN ATOMIC 
    DECLARE price DECIMAL(10,3); 

    IF Vendor = 'Vendor 1' 
      THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid); 
    ELSE IF Vendor = 'Vendor 2' 
      THEN SET price = (SELECT Price FROM V2Table WHERE Pid = GetPrice.Pid); 
    END IF; 

    RETURN price; 
  END

この単純な関数は、取引先を特定する入力パラメーターの値に基づいて、スカラー価格値を戻します。 また、IF ステートメントも使用します。

出力パラメーター、結果セットの受け渡し、さらに高度な他のプロシージャー型のエレメントを必要とする複雑なロジックの場合は、SQL のプロシージャーのほうが適しているかもしれません。