【问题标题】:SQL Server trigger won't run the complete update statement?SQL Server 触发器不会运行完整的更新语句?
【发布时间】:2013-04-01 10:58:55
【问题描述】:

问题:我编写了一个触发器,它应该在 INSERTLINE 表之后更新 INVOICE 表,但它不会更新发票表。触发器触发,但Update 语句块不会执行。

我在将INSERT 执行到行表中时进行了调试,发现一旦它到达UPDATE 语句,它就会跳过它并且不运行该代码。这几天我一直在尝试解决这个问题。

这是我的触发代码

ALTER TRIGGER [dbo].[trgInvoiceInsert] ON [dbo].[LINE]
AFTER INSERT
AS
  declare @linUnits numeric(9,2);
  declare @linPrice numeric(9,2);
  declare @invNum   int;

  select @linUnits = LINE_UNITS from inserted;
  select @linPrice = LINE_PRICE from inserted;
  select @invNum = INV_NUMBER from inserted;
BEGIN
 UPDATE i --From here it jumps to the start of the next Update
    SET INV_SUBTOTAL = INV_SUBTOTAL + (@linUnits * @linPrice)
 FROM dbo.INVOICE as i
 WHERE i.INV_NUMBER = @invNum 

 UPDATE i
    SET INV_TOTAL = INV_SUBTOTAL + INV_TAX  
 FROM dbo.INVOICE as i
 WHERE i.INV_NUMBER = @invNum 


 PRINT 'Trigger fired Successfully.'

结束

【问题讨论】:

  • 这是通常的行为,即跳转,因为 update-set-from-where 是一条语句,并按原样执行。我会冒险猜测INV_SUBTOTAL 开始无效。您添加到 null 的任何内容都将保持为 null。尝试将INV_SUBTOTAL = INV_SUBTOTAL+ ... 替换为INV_SUBTOTAL = isnull(INV_SUBTOTAL, 0) + ...。如果这样做不行,请在第一个 UPDATE 之后添加 print @@rowcount 并在 messages 窗格中观察结果。如果你看到零,那么你就会知道@invnum 有问题。
  • 哦,听听 marc_s 的建议。这只是为了找出您当前实现无法正常工作的原因,但您应该尝试使用基于invoice 和派生表select INV_NUMBER, sum(LINE_UNITS * LINE_PRICE) total from inserted group by INV_NUMBER 之间连接的更新替换变量。
  • 非常感谢!带有 null 的 INV_SUBTOTAL 所以我调整了它,它工作正常。我来这里的次数比花几天时间拔头发的次数还要多。我真的很感激。

标签: sql tsql triggers sql-server-2008-r2


【解决方案1】:

好吧,使用这样的语句:

select @linUnits = LINE_UNITS from inserted;

表示您假设触发器每行触发 - 它确实

SQL Server 触发器每条语句触发一次 - 因此,如果您的语句将多行插入Line 表中,您的触发器将触发一次完整的语句,但Inserted 伪表将包含多行数据。

因此,您需要重写触发器以考虑到这一点 - Inserted 表可以(并且将!)包含多行 - 您的触发器代码需要处理这一点。

【讨论】:

  • @АртёмЦарионов:刚刚修正了一些错别字,用反引号突出显示表名以使其脱颖而出,使用SQL Server 而不是SQL - 类似的东西......
  • 听起来你手头有很多时间 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 2011-06-03
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多