【发布时间】:2023-03-24 06:40:02
【问题描述】:
我举一个例子来说明我的问题。我创建了一个这样的表:
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 表中一无所获。
我意识到当我 ROLLBACK 然后 + 表 a 中的数据被回滚(我知道)并且 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 表中的数据虽然已回滚,但并未删除。
帮我深入解释一下触发器内部发生了什么?
【问题讨论】:
-
欢迎!,你说
data in INSERTED table is also removed.Why is that?你确定吗?我执行了你的代码,一切似乎都很好!,也将 RAISERROR 命令更改为RAISERROR(' I am In the Begin and End block after inserting into inserted table',12,1)以获取更多说明,也请通知 the data is existing into inserted table only while executing DML commands then the data has gone。 -
inserted可以包含 0、1 或 多个 行。如果有人插入了多行,其中 some 有id1,那么 a) 触发器应该做什么,b) 您当前的触发器只选择ids 之一,因此可能不会做出反应。为什么你不只是有一个check约束呢? -
@Damien_The_Unbeliever,我只是举一个简单的例子来澄清我的问题。我的问题只是为什么在 ROLLBACK 时删除了 INSERTED 表中的数据
标签: sql-server triggers transactions insert rollback