INSTEAD OF SQL トリガー
INSTEAD OF トリガーとは、SQL UPDATE ステートメント、DELETE ステートメントまたは INSERT ステートメントの「代わりに」処理される SQL トリガーです。 SQL 前トリガーや後トリガーとは異なり、INSTEAD OF トリガーを定義できるのはビューのみで、表では定義できません。
INSTEAD OF トリガーは、本質的には挿入、更新、削除ができないビューで、挿入、更新、削除を可能にします。 削除可能、更新可能、挿入可能の各ビューについての詳細は、CREATE VIEW を参照してください。
つまり、SQL INSTEAD OF トリガーをビューに追加すると、それまでは読み取りしかできなかったビューが、挿入、更新、または削除操作のターゲットとして使用できるようになります。 INSTEAD OF トリガーはビューを保守するために必要な操作を定義します。
表へのアクセスを制御するためにビューを使用できるようになります。 INSTEAD OF トリガーは、表へのアクセス制御の保守を単純化します。
INSTEAD OF トリガーの使用
CREATE TABLE T1 (C1 VARCHAR(10), C2 INT)
CREATE VIEW V1(X1) AS SELECT C1 FROM T1 WHERE C2 > 10
INSERT INTO V1 VALUES('A')
CREATE TRIGGER IOT1 INSTEAD OF INSERT ON V1
REFERENCING NEW AS NEW_ROW
FOR EACH ROW MODE DB2SQL
INSERT INTO T1 VALUES(NEW_ROW.X1, 15)
ビューを削除可能にする
CREATE TABLE A (A1 VARCHAR(10), A2 INT)
CREATE VIEW V1(X1) AS SELECT A1 FROM A
CREATE TABLE B (B1 VARCHAR(10), B2 INT)
CREATE VIEW V2(Y1) AS SELECT B1 FROM B
CREATE VIEW V3(Z1, Z2) AS SELECT V1.X1, V2.Y1 FROM V1, V2 WHERE V1.X1 = 'A' AND V2.Y1 > 'B'
CREATE TRIGGER IOT2 INSTEAD OF DELETE ON V3
REFERENCING OLD AS OLD_ROW
FOR EACH ROW MODE DB2SQL
BEGIN
DELETE FROM A WHERE A1 = OLD_ROW.Z1;
DELETE FROM B WHERE B1 = OLD_ROW.Z2;
END
DELETE FROM V3 WHERE Z1 = 'A' AND Z2 = 'X'
複数の視点で定義された視点を持つ INSTEAD OF トリガー
CREATE TABLE T1 (C1 VARCHAR(10), C2 INT)
CREATE TABLE T2 (D1 VARCHAR(10), D2 INT)
CREATE VIEW V1(X1, X2) AS SELECT C1, C2 FROM T1
UNION SELECT D1, D2 FROM T2
CREATE VIEW V2(Y1, Y2) AS SELECT X1, X2 FROM V1
CREATE TRIGGER IOT1 INSTEAD OF UPDATE ON V1
REFERENCING OLD AS OLD_ROW NEW AS NEW_ROW
FOR EACH ROW MODE DB2SQL
BEGIN
UPDATE T1 SET C1 = NEW_ROW.X1, C2 = NEW_ROW.X2 WHERE
C1 = OLD_ROW.X1 AND C2 = OLD_ROW.X2;
UPDATE T2 SET D1 = NEW_ROW.X1, D2 = NEW_ROW.D2 WHERE
D1 = OLD_ROW.X1 AND D2 = OLD_ROW.X2;
END
ビュー V2 の元の定義が更新不可のままになるため、ビュー V2 も更新不可のままになります。
前トリガーおよび AFTER のトリガー INSTEAD OF との使用
CREATE TABLE T1 (C1 VARCHAR(10), C2 DATE)
CREATE TABLE T2 (D1 VARCHAR(10))
CREATE TRIGGER AFTER1 AFTER DELETE ON T1
REFERENCING OLD AS OLD_ROW
FOR EACH ROW MODE DB2SQL
DELETE FROM T2 WHERE D1 = OLD_ROW.C1
CREATE VIEW V1(X1, X2) AS SELECT SUBSTR(T1.C1, 1, 1), DAYOFWEEK_ISO(T1.C2) FROM T1
CREATE TRIGGER IOT1 INSTEAD OF DELETE ON V1
REFERENCING OLD AS OLD_ROW
FOR EACH ROW MODE DB2SQL
DELETE FROM T1 WHERE C1 LIKE (OLD_ROW.X1 CONCAT '%')
ビュー V1 に対する削除処理を行うことで、結果的に AFTER DELETE トリガーである AFTER1 が活動化されます。これは、 トリガー IOT1 が表 T1 上で削除を実行するためでもあります。つまり、表 T1 の削除が結果的に AFTER1 トリガーを活動化します。
依存関係にある視点と INSTEAD OF トリガー
ビューに INSTEAD OF トリガーを追加するときに、 ビューの定義が複数のビューを参照し、その中に INSTEAD OF トリガーを定義したビューが含まれる場合は、UPDATE、DELETE、および INSERT の 3 種類すべての操作について、INSTEAD OF トリガーを定義します。その際、定義されたビューの機能と、その他の依存関係にあるビューがもつ機能とが混乱しないようにします。