ページの先頭行へ戻る
Symfoware Server V10.0.0 アプリケーション開発ガイド(共通編)

10.1 トリガ定義

トリガ定義は、CREATE TRIGGER文で行います。トリガ定義では、トリガ事象と、起動する手続きを指定します。トリガ事象は、トリガを起動するきっかけとなる表に対するデータの更新方法を指定します。また、起動する手続きは、処理したい手続きを被トリガSQL文で指定します。

ここでは、トリガの利用目的によって、以下のように分類します。

単純なトリガ

表に対する更新を契機にして、別の表にデータを挿入するINSERT文を定義して自動的に実行することができます。

プロシジャルーチンを呼び出すトリガ

トリガの被トリガSQL文にCALL文を指定して、プロシジャルーチンを呼び出すことができます。

プロシジャルーチンを使用することによって、複数のSQL文で構成する処理手続きを被トリガSQL文として定義することができます。また、業務要件に応じたデータの整合性や一貫性を自由にカスタマイズすることができます。

たとえば、データの整合性や一貫性を保証する手続きを定義したプロシジャルーチンをトリガにより呼び出し、表間のデータの整合性を保証したり、更新するデータの値をチェックしたりすることができます。

トリガを使用すると、これらの情報の設定をシステムで自動的に実行することができるため、アプリケーションを簡素化でき、信頼性の高いシステムを構築することができます。

以下に、トリガの定義例を示します。

例1 単純なトリガの場合

発注表に追加された行の発注価格が500万を超えている場合、トリガ“発注トリガ”により、その製品の取引先、仕入価格および発注数量を高額発注表に追加します。

トリガ定義例

CREATE TRIGGER  STOCKS.発注トリガ
  AFTER INSERT ON STOCKS.発注表
  REFERENCING NEW AS NEWREC
  FOR EACH ROW
    WHEN(NEWREC.仕入価格 * NEWREC.発注数量 > 5000000)
    INSERT INTO STOCKS.高額発注表
    VALUES(NEWREC.取引先,NEWREC.仕入価格,NEWREC.発注数量)


例2 プロシジャルーチンを呼び出すトリガの場合

発注表に行を挿入すると、トリガ“発注トリガ2”により、プロシジャルーチン“発注ルーチン”を呼び出します。“発注ルーチン”は、挿入データに対して整合性チェックを行います。そして、発注した製品の在庫数量について在庫表を更新します。

プロシジャルーチン定義例

CREATE PROCEDURE STOCKS.発注ルーチン (
    IN  NEW取引製品    SMALLINT,
    IN  NEW発注数量    SMALLINT
)
BEGIN
    -- SQL変数宣言
    DECLARE SQLSTATE    CHAR(5);
    DECLARE SQLMSG      CHAR(256);
    DECLARE POINT       SMALLINT;
    DECLARE S在庫数量  INTEGER;
    -- 条件宣言
    DECLARE 入力発注数量不当    CONDITION FOR SQLSTATE'60001';
    DECLARE 入力製品番号不当    CONDITION FOR SQLSTATE'60002';
    DECLARE 在庫不足            CONDITION FOR SQLSTATE'60003';
    DECLARE その他異常          CONDITION FOR SQLSTATE'60999';
    -- ハンドラ宣言
    DECLARE EXIT HANDLER FOR NOT FOUND
    BEGIN
        IF (POINT = 20 OR POINT = 30) THEN
            RESIGNAL 入力製品番号不当
                     '発注: 入力異常: 取引製品の値が不当';
        ELSE
            RESIGNAL その他異常 '発注: 異常: 予想外のデータなし発生';
        END IF;
    END;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
    BEGIN
  
  
  
        RESIGNAL;  --発生したエラーをそのまま返却する
    END;
    -- 本処理
    -- (1)入力チェック
    SET POINT = 10;
    IF (NEW発注数量 < 1) THEN
        SIGNAL 入力発注数量不当 '発注: 入力異常: 発注数量の値が不当';
    END IF;
    -- (2)在庫数量チェック
    SET POINT = 20;
    SELECT 在庫数量 INTO S在庫数量 FROM STOCKS.在庫表
        WHERE 製品番号 = NEW取引製品
        WITH OPTION LOCK_MODE(EXCLUSIVE LOCK);
    IF (NEW発注数量 > S在庫数量) THEN
        SIGNAL 在庫不足 '発注: 異常: 在庫不足です';
    END IF;
    -- (3)発注作業
    SET POINT = 30;
    UPDATE STOCKS.在庫表
        SET 在庫数量 = 在庫数量 - NEW発注数量
        WHERE 製品番号 = NEW取引製品;
END

トリガ定義例

CREATE TRIGGER STOCKS.発注トリガ2
    AFTER INSERT ON STOCKS.発注表
    FOR EACH ROW
    CALL STOCKS.発注ルーチン(NEW.取引製品, NEW.発注数量);

注)“発注ルーチン”が不当な入力値を検出した際、INSERT文は以下のエラーになります。
「JYP1065E スキーマ “STOCKS”のトリガ“発注トリガ2”の被トリガ SQL文でエラーが発生しました.詳細メッセージ= JYP2550E SIGNAL文により例外が送信されました.例外メッセージ=“発注: 異常: 在庫不足です”」

上記のように、プロシジャルーチンとトリガを定義して、表を更新するSQL文を実行すると、被トリガSQL文で指定したプロシジャルーチンが自動的に実行され、データの一貫性を損なうような更新を抑止することができます。また、プロシジャルーチン中で、お互いに参照関係にある表の結合列の存在をチェックして表間のデータの整合性を保証したり、親となる表の行を削除する契機で、対応する子となる表のデータを自動的に削除したりするようなトリガを定義することもできます。

ただし、複雑な業務ロジックは、トリガで定義しないようにしてください。トリガは起動元となった表の更新の延長で動作します。トリガの中でトランザクションを制御することはできません。複雑な業務ロジックはプロシジャルーチンで作成し、アプリケーションから直接プロシジャルーチンをCALLするようにしてください。

トリガの動作

トリガは以下のように動作します。

トリガ定義での注意事項

トリガ定義での注意事項を、以下に示します。