DMLトリガーを作成する
データベーストリガーの中でももっとも一般的なDMLトリガーの作成方法と簡単な使用方法を記載していきます。
トリガーとは?
トリガーとはあるイベントが発生した場合に自動的に実行されるプロシージャです。
下記のイベント発生時にトリガーを起動させることができます。
- DML(DELETE, INSERT, UPDATE)
- DDL(CREATE, ALTER, DROP)
- データベース処理(SERVERERROR, LOGON, LOGOFF, STARTUP, SHUTDOWN)
トリガーの作成方法
トリガーは、CREATE TRIGGER句を使用して作成します。
OR REPLACEオプションを指定すると同名のトリガーを上書きします。
CREATE [OR REPLACE] TRIGGER トリガー名
トリガーの起動タイミングを指定します。
BEFOREはテーブル更新前、AFTERはテーブル更新後にトリガーを起動させます。
{BEFORE | AFTER | INSTEAD OF}
トリガーの起動イベントを指定します。
{INSERT OR UPDATE OR DELETE}
トリガーの起動対象テーブルを指定します。
ON テーブル名
トリガーの起動回数を指定します。
FOR ECACH ROWオプションを指定すると行トリガーになり、指定しないと文トリガーになります。
行トリガーはレコードの更新毎、文トリガーはテーブルの更新毎に起動します。
1回の処理で複数行が更新された場合には、行トリガーは行数分、文トリガーは1回のみトリガーが起動します。
[FOR EACH ROW]
トリガーの起動条件を指定します。
WHENオプションを指定すると一定の条件を満たした場合にのみトリガーを起動させることができます。
[WHEN 条件式]
EMPテーブルのUPDATE後に起動する行トリガーを作成する場合
CREATE [OR REPLACE] TRIGGER トリガー名 AFTER UPDATE ON EMP FOR EACH ROW
トリガー本体の作成
起動イベントでINSERT OR UPDATE OR DELETEとした場合に、トリガー内で処理を分岐するにはDMLの種類を評価します。
IF INSERTING THEN -- INSERTの場合 ... ELSIF UPDATING THEN -- UPDATEの場合 ... ELSIF DELETING THEN -- DELETEの場合 ... END IF;
トリガー内で更新前後の値を参照するには、バインド変数(ホスト変数):old.列名、new.列名で参照することができます。
ただし、値が参照できるのは行トリガーのみで文トリガーは参照できません。
また、起動イベントによりold/newに格納される値が異なります。
起動イベント | old | new |
---|---|---|
INSERT | NULL | 更新後値 |
UPDATE | 更新前値 | 更新後値 |
DELETE | 更新前値 | NULL |
DMLの種類を判定して更新前後の値を表示する。
BEGIN IF INSERTING THEN DBMS_OUTPUT.PUT_LINE('DML:INSERT' || ' 更新後値:' || :new.name); ELSIF UPDATING THEN DBMS_OUTPUT.PUT_LINE('DML:UPDATE' || ' 更新前値:' || :old.name || ' 更新後値:' || :new.name); ELSIF DELETING THEN DBMS_OUTPUT.PUT_LINE('DML:DELETE' || ' 更新前値:' || :old.name); END IF; END;
トリガーからプロシージャを起動する。
BEGIN IF INSERTING THEN insert_proc(:new.name); ELSIF UPDATING THEN update_proc(:old.name, :new.name); ELSIF DELETING THEN update_proc(:old.name); END IF; END; /
トリガー使用時の注意点
- トリガー内の処理でCOMMITやROLLBACKは禁止
トリガーは上位のトランザクションよる起動されるので、トリガー内でCOMMITを行うと、上位のトランザクションでROLLBACKができなくなります。 - 起動対象テーブルへのデータ更新
例えば、UPDATEイベントで起動されるトリガ内でデータ更新をすると、メモリがなくなるまで再帰処理を続けます。