SQL Server AFTER INSERT触发器每次插入多次更新第二个表

时间:2017-11-24 15:31:30

标签: sql-server triggers

这让我很难过。我们有一个带有AFTER INSERT触发器的事务表,用于更新customer表中的余额。触发器将针对单个客户在插入的虚拟表中触发多行,这是完全正常的。

示例:

客户余额为500

在事务表上进行INSERT,为客户生成多行,第一行是50借记,第二行是100借记​​。

预期结果发布后触发器是客户余额为350.实际结果为450,因为看起来客户触发器中的连接每次都返回相同的余额,而不是上一行更新后的余额。 / p>

插入#1取余额500并从中扣除50 插入#2取500而不是450的余额并从中扣除100

这是触发器:

CREATE TRIGGER [dbo].[tBalances] 
ON  [dbo].[tblCustomerTransaction]
AFTER INSERT
AS 
BEGIN
    IF @@ROWCOUNT = 0 RETURN
    SET NOCOUNT ON; 

    UPDATE  C
    SET     C.AvailableBalance = C.AvailableBalance + CASE WHEN TT.bIsDebit = 1 THEN I.decAmount * -1 ELSE I.decAmount END,
            C.BonusBalance = C.BonusBalance + CASE WHEN TT.bIsDebit = 1 THEN I.decBonusAmount * -1 ELSE I.decBonusAmount END
    FROM    inserted AS I
            INNER JOIN tblCustomer AS C ON I.iCustomerID = C.CustomerId         
            INNER JOIN tblTransactionType AS TT ON I.iTransactionTypeID = TT.iTransactionTypeID         
    WHERE   I.iManagerID = 12345
END

为什么客户表更新不会插入插入的每一行?

1 个答案:

答案 0 :(得分:1)

如果手动计算这些聚合(而不是仅仅定义索引视图并让SQL Server自动维护它们),请确保每个目标行仅受一次更新 - 使用分组:

UPDATE  C
SET     C.AvailableBalance = C.AvailableBalance + BalanceChange,
        C.BonusBalance = C.BonusBalance + BonusChange
FROM    (SELECT iCustomerID,
           SUM(CASE WHEN TT.bIsDebit = 1 THEN I.decAmount * -1
                                         ELSE I.decAmount END)
           as BalanceChange,
           SUM(CASE WHEN TT.bIsDebit = 1 THEN I.decBonusAmount * -1
                                         ELSE I.decBonusAmount END)
           as BonusChange
        FROM inserted AS I
        INNER JOIN tblTransactionType AS TT ON I.iTransactionTypeID = TT.iTransactionTypeID
        WHERE   I.iManagerID = 12345
        GROUP BY iCustomerID) t
 INNER JOIN tblCustomer AS C ON t.iCustomerID = C.CustomerId

(如果不完全正确,希望您能看到这对您的真实查询有何影响)