問題を示す例を挙げます。次のようにテーブルを作成します。
CREATE TABLE a
(
id INT
)
AFTER INSERTトリガーを作成して、id = 1をテーブル "a"に挿入できないようにします
CREATE TRIGGER [dbo].[insert_a]
ON [dbo].[a] AFTER INSERT
AS
BEGIN
DECLARE @id INT
SELECT @id=id FROM inserted
IF @id=1
BEGIN
RAISERROR('1',12,1)
ROLLBACK;
END
SELECT * FROM inserted
END
次に、id = 1をテーブル "a"に挿入します。
INSERT INTO a VALUES(1)
INSERTEDテーブルから何も取得されません。
次にロールバックすると、次のことがわかります。
テーブル "a"のデータはROLLBACKでした(知っています)
iNSERTEDテーブルのデータも削除されます。なぜですか?
トリガーでAFTER INSERTをINSTEAD OF INSERTに変更した場合。
ALTER TRIGGER [dbo].[insert_a]
ON [dbo].[a] INSTEAD OF INSERT
AS
BEGIN
DECLARE @id INT
SELECT @id=id FROM inserted
IF @id=1
BEGIN
RAISERROR('1',12,1)
ROLLBACK
END
SELECT * FROM inserted
END
INSERT INTO a VALUES(1)
次に、結果を取得します。
id
1
つまり、INSERTEDテーブルのデータはROLLBACKされていても削除されません。
説明してくれませんか?
どちらの場合も、行は挿入されていません。
ために after insert
トリガーのロールバックはトランザクションの一部です。詳細については、このQ&Aを参照してください。
上記Q&Aより引用。
1つ(または複数)の行をテーブルに挿入しています。次に、まだトランザクション内で、AFTER INSERTトリガーが実行され、特定の条件をチェックします。通常、トリガー内で使用可能なInserted疑似テーブルを使用します。これには、挿入された行が含まれます。
トリガーでROLLBACK TRANSACTIONを呼び出すと、はい-トランザクションはすべての処理が行われた状態でロールバックされ、INSERTが発生しなかったかのように、データベーステーブルには何も表示されません。
ために instead of trigger
表示されている1のid値は、テーブルのものではありません。これはトリガー内のコードからのものです。この1の値は、
SELECT * FROM inserted
このコードを実行すると、レコードは返されません。
ALTER TRIGGER [dbo].[insert_a]
ON [dbo].[a] INSTEAD OF INSERT
AS
BEGIN
DECLARE @id INT
SELECT @id=id FROM inserted
IF @id=1
BEGIN
RAISERROR('1',12,1)
ROLLBACK
END
SELECT * FROM inserted
END
GO
INSERT INTO a VALUES(1);
GO
SELECT * FROM dbo.a;
GO