【发布时间】:2017-11-24 15:31:30
【问题描述】:
这让我很难过。我们有一个带有 AFTER INSERT 触发器的事务表,用于更新客户表中的余额。触发器将在为单个客户插入的虚拟表中触发多行是完全正常的。
例子:
客户余额为 500
在为客户生成多行的交易表上进行 INSERT,第一行是 50 借方,第二行是 100 借方。
预期结果后触发器是客户余额为 350。实际结果是 450,因为看起来触发器中的联接到客户每次返回相同的余额,而不是前一行更新后的余额。
insert #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)SQL Server 触发器总是语句级别 2)All-at-once 原则
-
UPDATEs(和其他 DML)好像所有行都在同时受到影响。没有“前一行”需要考虑。您是否有理由不只是使用索引视图自动维护这些聚合? -
好吧,这是有道理的。这个问题的解决方案是什么?确定不是光标循环?
标签: sql-server triggers