【问题标题】:SQL Server : trigger after transactionSQL Server:事务后触发
【发布时间】:2016-09-29 07:34:34
【问题描述】:

我在更新表后有一个触发器,并且一个事务中有 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)

【问题讨论】:

  • 请注意,SQL Server 中的触发器是set-based。因此它将立即对整个集合(更新)执行其操作。您能否分享触发器中的代码并检查它是否正确处理了这种基于集合的方法?
  • 你的问题不清楚。我假设你在问..you have two updates in one transaction and you want your trigger to be called for second update only on same table ?
  • 如果 (3) 没有对表进行进一步更改,则在 (2) 处的触发器中观察到的表与 (4) 处的相同。我不明白问题是什么。
  • 触发器仅在第一次更新后运行。没关系。但是在这个事务中存在另一个更新,它更新了数据。我要触发已看到新数据(如果触发在事务中)。
  • 看起来示例代码有问题,因为第一次更新(其中aaa = 123)不会满足触发器内部的条件(其中deleted.aaa为null),所以不会既不是第一次也不是第二次插入到导出中。

标签: sql-server triggers transactions


【解决方案1】:

我明白你的问题了。

但是,SQL Server 中的触发器是语句级别的,不幸的是它们的工作方式与您在这里所期望的不同。您可能可以通过向表中添加一些“控制”列(在事务的最后更新它并围绕它创建一些逻辑)或使用 context_info 来使其工作,但它真的闻起来恕我直言。

远离触发器并从主范围插入导出表,这是您的最佳选择。

【讨论】:

  • 这样的事情开始让我开始考虑在我的下一个项目中使用 Postgres - 现在 Postgres 中有如此多的数据建模和应用程序级功能,这使得 SQL Server 看起来非常过时......就像 2021 年和 SQL Server仍然不支持可延迟约束、未记录表、表继承等等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2014-10-23
  • 2012-11-13
  • 1970-01-01
相关资源
最近更新 更多