SQL Serverでトリガーを作成する場合、トリガーステートメント(つまり、トリガーを起動したSQLステートメント)と組み合わせて起動するか、代わりに起動するかを選択できます。 その声明の。
代わりにトリガーを起動するには トリガーステートメントのINSTEADOF
を使用します 引数。
これは、 FOR
を使用するのとは対照的です。 またはAFTER
引数。これらの引数を使用すると、トリガーとなるSQLステートメントで指定されたすべての操作が正常に起動した場合にのみトリガーが起動します。
例
サンプルテーブルを作成します:
CREATE TABLE t1 (
id int IDENTITY(1,1) NOT NULL,
c1 int DEFAULT 0,
c2 int DEFAULT 0,
c3 int DEFAULT 0
);
トリガーを作成します:
CREATE TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted);
サンプル行を挿入します:
INSERT INTO t1 (c1, c2, c3)
VALUES (1, 1, 1);
SELECT * FROM t1;
これまでのところ、次のとおりです。
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 1 | +------+------+------+------+
それでは、 UPDATE
を実行してみましょう。 テーブルに対するステートメント(これによりトリガーが起動されます)。
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
結果:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 2 | +------+------+------+------+
予想どおり、 UPDATE
トリガーステートメントのステートメントは、トリガーのステートメントに置き換えられました。
私のトリガーは、テーブルの更新が試行されるたびに、 c3
を更新するように指定しました 代わりに列。
特定の列が更新された場合にのみ実行
UPDATE()
を使用することもできます 指定した列が更新されたときにのみ実行するコードを指定する関数。
たとえば、トリガーを次のように変更できます。
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF UPDATE
AS
IF ( UPDATE(c1) )
BEGIN
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM inserted)
END;
次に、前の UPDATE
を実行します もう一度声明:
UPDATE t1
SET c1 = c1 + 1
WHERE id = 1;
SELECT * FROM t1;
結果:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
繰り返しますが、 c3
列がインクリメントされます。
しかし、今度は c2
を更新してみましょう。 列:
UPDATE t1
SET c2 = c2 + 1
WHERE id = 1;
SELECT * FROM t1;
結果:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 3 | +------+------+------+------+
何も変わりません。 c3
列は同じままです。
c2
でさえありません 列が更新されます。これは、トリガーステートメントの代わりにトリガーが引き続き実行されるためです。
DELETEの代わりにトリガーを実行する
DELETE
の代わりに実行するようにトリガーを変更できます ステートメント。
ALTER TRIGGER trg_t1
ON t1
INSTEAD OF DELETE
AS
UPDATE t1
SET c3 = c3 + 1
WHERE id IN (SELECT DISTINCT id FROM deleted);
それでは、すべての行を削除してから、テーブルからすべての行を選択してみましょう。
DELETE FROM t1;
SELECT * FROM t1;
結果:
+------+------+------+------+ | id | c1 | c2 | c3 | |------+------+------+------| | 1 | 1 | 1 | 4 | +------+------+------+------+
このトリガーが正しく機能するためには、 deleteed
にクエリを実行する必要があることに注意してください。 トリガーのテーブル(挿入
とは対照的) 前の例の表)。
これらの2つのテーブルは、SQLServerによって作成および管理されます。
削除コード> テーブルには、
DELETE
中に影響を受ける行のコピーが格納されます およびUPDATE
ステートメント。 DELETE
の実行中 またはUPDATE
ステートメントでは、行はトリガーテーブルから削除され、削除されたテーブルに転送されます。
挿入コード> テーブルには、
INSERT
中に影響を受ける行のコピーが格納されます およびUPDATE
ステートメント。挿入または更新トランザクション中に、挿入されたテーブルとトリガーテーブルの両方に新しい行が追加されます。挿入されたテーブルの行は、トリガーテーブルの新しい行のコピーです。
注意すべきいくつかの制限
最大1つのINSTEADOF
を定義できます INSERT
ごとのトリガー 、 UPDATE
、または DELETE
テーブルまたはビューのステートメント。
INSTEAD OF
を定義することはできません WITH CHECK OPTION
を使用する更新可能なビューでトリガーします 。