【问题标题】:ROLLBACK make data in INSERTED table is removed in AFTER INSERT TRIGGERROLLBACK 使 INSERTED 表中的数据在 AFTER INSERT TRIGGER 中删除
【发布时间】: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 或 多个 行。如果有人插入了多行,其中 someid 1,那么 a) 触发器应该做什么,b) 您当前的触发器只选择 ids 之一,因此可能不会做出反应。为什么你不只是有一个check 约束呢?
  • @Damien_The_Unbeliever,我只是举一个简单的例子来澄清我的问题。我的问题只是为什么在 ROLLBACK 时删除了 INSERTED 表中的数据

标签: sql-server triggers transactions insert rollback


【解决方案1】:

据我所知,这是预期的行为。只是根据你的看法,AFTER 可能有点误导。

“触发器和触发它的语句被视为单个事务,可以从触发器内部回滚。如果检测到严重错误,整个事务会自动回滚。”。

https://msdn.microsoft.com/en-us/library/ms178110.aspx

【讨论】:

    猜你喜欢
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多