有时SQL Server触发器不会触发

时间:2012-11-09 06:50:10

标签: sql sql-server sql-server-2008

我在recharge表上创建了一个触发器。它会更新onaccountregistry表的余额。

但有时候在我的recharge表中插入行时,它不会触发触发器。然后价值不匹配。这个recharge表每次都插入行。

我按如下方式创建了触发器。这不是复制表。我正在使用SQL Server 2008企业版。

请帮我解决这个问题

CREATE TRIGGER [dbo].[RechargeRefund] 
   ON [dbo].[ISRecharge]  
   FOR INSERT  
AS
   declare @tin char(9) 
   declare @depocd char(1) 
   declare @oldvalue money
   declare @newvalue money
begin
    select @tin = inserted.tin_subtin from inserted
    select @depocd = inserted.updatetype from inserted
    select @newvalue = inserted.DepositAmt from inserted
    select @oldvalue = Totdeposit from ISOnAcctRegistry where tin_subtin = @tin
end

if @depocd ='1'
begin
  update ISOnAcctRegistry
  set Totdeposit = @oldvalue + @newvalue
  where tin_subtin = @tin
end 

if @depocd ='2'
begin
  update ISOnAcctRegistry
  set Totdeposit = @oldvalue - @newvalue
  where tin_subtin = @tin
end
GO

2 个答案:

答案 0 :(得分:3)

正如@marc所指出的那样,假设inserted中的单行是错误的 - 甚至可以从inserted中选择3个来自3个不同的3个变量的值(任意) )来自inserted的行。

你可能想要的是:

update i1
set Totdeposit = Totdesposit + t2.Total
from ISOnAcctRegistry i1
        inner join
     (select
         tin_subtin,
         SUM(CASE updatetype
              WHEN 1 THEN DepositAmt
              WHEN 2 THEN -DepositAmt
         ELSE 0 END) as Total
      from inserted
      group by tin_subtin) t2
        on
            i1.tin_subtin = t2.tin_subtin

但您可以使用基于ISOnAcctRegistry构建的索引视图替换此作品(以及ISRecharge中的此列) - 但有一些限制,您可以构建一个在SUM中的行中自动执行ISRecharge的视图,SQL Server将负责为您在后台维护值。

显然,目前,您的触发器不会考虑UPDATE上的任何DELETEISRecharge活动。索引视图会。

答案 1 :(得分:2)

嗯,当然它不起作用 - 你假设每行插入触发器触发一次

但那是的情况。

触发器每INSERT批次触发一次,伪表Inserted可能包含多行

如果你确实得到了一行INSERT,那么你的陈述选择了哪一行?

select @tin = inserted.tin_subtin from inserted
select @depocd = inserted.updatetype from inserted
select @newvalue = inserted.DepositAmt from inserted
select @oldvalue = Totdeposit from ISOnAcctRegistry where tin_subtin = @tin

您需要重写触发器,以便在Inserted中处理多行 - 然后每次都会有效。