アプリケーション開発の手引き

トリガー・アクション

トリガーを活動化すると、それに関連するトリガー・アクションが実行されます。すべてのトリガーには、次のような 2 つの構成要素を順々に持つトリガー・アクションが 1 つだけあります。

トリガー・アクション条件は、トリガー・アクションが実行中の行やステートメントに対してトリガー・ステートメントのセットが実行されるかどうかを定義します。トリガー・ステートメントのセットは、トリガー事象が発生した結果としてトリガーによりデータベースで実行される一連のアクションを定義します。

たとえば以下のトリガー・アクションは、 on_hand 列の値が max_stocked 列の値の 10 パーセントより小さい行に対してのみ、トリガー SQL ステートメントのセットが活動化されることを指定します。この場合、トリガー SQL ステートメントのセットが issue_ship_request 関数を呼び出します。

    CREATE TRIGGER REORDER
      AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS
      REFERENCING NEW AS N_ROW
      FOR EACH ROW MODE DB2SQL
      WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED)
      BEGIN ATOMIC
        VALUES(ISSUE_SHIP_REQUEST(N_ROW.MAX_STOCKED -
                                  N_ROW.ON_HAND,
                                  N_ROW.PARTNO));
      END

トリガー・アクション条件

トリガー・アクションで説明したように、 トリガー・アクション条件 は、探索条件を指定するトリガー・アクションの任意指定の文節です。トリガー・アクション内で SQL ステートメントを実行するためには、探索条件は と評価されなければなりません。 WHEN 文節を省略すると、トリガー・アクション内の SQL ステートメントは常に実行されます。

トリガー・アクション条件は、FOR EACH ROW トリガーの場合にはそれぞれの行に対して一度評価され、 FOR EACH STATEMENT トリガーの場合にはステートメントに対して一度評価されます。

さらに WHEN 文節は、トリガーに代わって活動化されるアクションを正しく調整するために使用できるように制御されます。たとえばこの文節は、入ってくる値がある一定の範囲の内側か外側になる場合だけトリガー・アクションが活動化されるという、データ従属の規則を強調するのに役立ちます。

トリガー SQL ステートメント

トリガー SQL ステートメントのセットは、トリガーの活動化により行われる実際の アクションを実行します。前に説明したように、すべての SQL 操作がすべてのトリガーに有効となるわけではありません。トリガー活動化時間が BEFORE か AFTER かにより、異なる種類の操作がトリガー SQL ステートメントに適用されます。

トリガー SQL ステートメントのリストや、 BEFORE および AFTER トリガーの詳細については、 SQL 解説書 を参照してください。

ほとんどの場合、トリガー SQL ステートメントが負の戻りコードを戻すと、トリガー SQL ステートメントはトリガーおよび参照を制約するすべてのアクションとともにロールバックされ、その結果エラー SQLCODE -723 (SQLSTATE 09000) が戻されます。その失敗したトリガー SQL ステートメントからは、トリガー名 SQLCODE、SQLSTATE、およびトークンの大部分が戻されます。トリガーの実行中に発生し、作業単位全体を否定またはロールバックするエラー条件は、 SQLCODE -723 (SQLSTATE 09000) では戻されません。

SQL トリガー・ステートメント内の関数

ユーザー定義関数 (UDF) を含む関数は、トリガー SQL ステートメント内で呼び出されます。次の例を考えます。

    CREATE TRIGGER REORDER
      AFTER UPDATE OF ON_HAND, MAX_STOCKED ON PARTS
      REFERENCING NEW AS N_ROW
      FOR EACH ROW MODE DB2SQL
      WHEN (N_ROW.ON_HAND < 0.10 * N_ROW.MAX_STOCKED)
      BEGIN ATOMIC
        VALUES (ISSUE_SHIP_REQUEST (N_ROW.MAX_STOCKED - N_ROW.ON_HAND,
                                         N_ROW.PARTNO));
      END

トリガー SQL ステートメントが非修飾の関数名を持つ関数呼び出しを含む場合、その関数呼び出しはトリガー作成時の関数パスに基づいて変換されます。関数の変換に関する詳細については、 SQL 解説書 を参照してください。

UDF は、C または C++ プログラミング言語で定義されます。 UDF は論理フローの制御、エラー処理と回復、システムおよびライブラリー関数へのアクセスを可能にします。 (UDF については、ユーザー定義関数 (UDF) とメソッドの作成で説明しています。) この機能を使うと、トリガー・アクションはトリガーが活動化された際に SQL 以外のタイプの操作を実行することができます。たとえばこのような UDF は、電子メールのメッセージを送信し、それにより警告機構として作用することができます。メッセージなどの外部アクションはコミット制御下にはなく、他のトリガー・アクションの成否に関係なく実行されます。

また関数はエラーが発生した結果、トリガー SQL ステートメントが失敗したことを示す SQLSTATE を戻すことがあります。これは、ユーザー定義の制約を実行する 1 つの方法です。 (SIGNAL SQLSTATE ステートメントを使用する方法もあります。) 複雑なユーザー定義の制約を検査する手段としてトリガーを使用するために、 RAISE_ERROR 組み込み関数をトリガー SQL ステートメントで使用することができます。この関数は、ユーザー定義の SQLSTATE (SQLCODE -438) をアプリケーションに戻すことができます。この関数の呼び出しと使用に関する詳細は、 SQL 解説書 を参照してください。

たとえば、EMPLOYEE 表の HIREDATE 列に関連する次のような規則を考えてください。この場合の HIREDATE は、従業員が作業を始める日付です。

以下のトリガーは、このような規則をすべて INSERT で処理します。

    CREATE TRIGGER CHECK_HIREDATE
      NO CASCADE BEFORE INSERT ON EMPLOYEE
      REFERENCING NEW AS NEW_EMP
      FOR EACH ROW MODE DB2SQL
      BEGIN ATOMIC
      VALUES CASE
        WHEN NEW_EMP.HIREDATE < CURRENT DATE
          THEN RAISE_ERROR('85001', 'HIREDATE has passed')
        WHEN NEW_EMP.HIREDATE - CURRENT DATE > 10000.
          THEN RAISE_ERROR('85002', 'HIREDATE too far out')
        WHEN NEW_EMP.HIREDATE - CURRENT DATE > 600.
          THEN SEND_MOTE('persmgr',NEW_EMP.EMPNO,'late.txt')
        END;
      END


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]