SQL Server:事务后触发器

3

我有一个在表上更新后触发的触发器,一个事务中有2个更新。触发器在第一个更新后被调用。我期望触发器在整个事务后再更新视图,但这并不是真实情况:

我的事务:

  1. 更新表
  2. 调用触发器,触发器只看到从1更新的数据
  3. 更新表
  4. 不会调用触发器,因为第3次更新的条件不匹配

是否可以设置触发器以便在事务完成后触发器查看数据(包括1和3)?

我的触发器:

ALTER TRIGGER "dbo"."TRIGGER" 
ON TABLE
FOR UPDATE
AS
    IF (SELECT COUNT(*) FROM inserted i, deleted d
        WHERE d.aaa IS NULL 
          AND i.aaa IS NOT NULL 
          AND i.bbb IN ('0', '1', '6', '9')) > 0
    BEGIN
        INSERT INTO export (aaa, ccc) 
            (SELECT aaa, ccc FROM inserted)
    END

初始化数据:insert into TABLE(aaa,bbb,ccc) values(123,'N',100)

更新:

update TABLE set bbb = '0' where aaa = 123
update TABLE set ccc = 1 where aaa = 123

期望的语句是:insert into export(123,1)

但实际执行的是:insert into export(123,100)


2
请注意,SQL Server中的触发器是“基于集合”的。因此,它会一次性对整个集合(update)执行其操作。你能否分享你的触发器代码,并检查它是否正确处理了这种基于集合的方法? - NickyvV
你的问题不够清楚。我猜你是在问:“你有一个事务中的两个更新操作,并且你希望触发器只在同一张表的第二次更新时被调用”,对吗? - TheGameiswar
如果(3)导致表格没有进一步的更改,那么触发器在(2)处观察到的表格与在(4)处的表格相同。我不明白问题出在哪里。 - Damien_The_Unbeliever
触发器仅在第一次更新后运行。这没问题。但是在这个事务中存在另一个更新,它更新了数据。我希望触发器能够看到新的数据(如果触发器在事务中)。 - Radoslav
看起来示例代码有问题,因为第一个更新(其中aaa = 123)不满足触发器内的条件(其中deleted.aaa为空),所以它既不会第一次也不会第二次插入到导出中。 - dean
我检查了我的代码。我添加了初始数据。bbb是字符,我希望它是正确的。它是从原始代码复制过来的,而且它能够工作。 - Radoslav
1个回答

3

我看到了你的问题。

然而,SQL Server中的触发器是语句级别的,不幸的是它们不能像你在这里期望的那样工作。你可能可以通过向表中添加一些“控制”列(在事务的最后更新它并创建一些逻辑)或使用context_info来使其工作,但这确实有点可疑。

远离触发器,并从主范围将插入操作进行到导出表,这是你最好的选择。


这种事情让我开始考虑在我的下一个项目中使用Postgres - 现在Postgres有很多数据建模和应用级功能,使得SQL Server看起来非常过时...就像现在是2021年了,SQL Server仍然不支持可延迟约束、非记录表、表继承等等。 - Dai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接