【发布时间】:2013-10-30 22:13:36
【问题描述】:
我正在处理一个触发器,当另一个表应用了插入或更新时,它将向表中插入行。到目前为止,Update 部分有效(我最关心的列是 Balance 列),但是当在 Account 表中添加第一行以进行插入时,在我的 AuditTrailCustomerBalance 表中 OldBalance、NewBalance 和 CustNo 设置为 NULL .如何让 NewBalance 和 CustNo 引用刚刚从触发器插入到表中的值?
这里是触发器:
ALTER TRIGGER AuditTrigger
ON Accounts
FOR INSERT, UPDATE
AS
IF UPDATE( Balance )
BEGIN
IF EXISTS
(
SELECT 'True'
FROM Inserted i
JOIN Deleted d
ON i.AccountID = d.AccountID
)
BEGIN
--1. Declare temp variables.
DECLARE @OldBalance NUMERIC( 18, 0 )
DECLARE @NewBalance NUMERIC( 18, 0 )
DECLARE @CustNo INT
--2. Set the variables.
SELECT @OldBalance = Balance FROM deleted
SELECT @NewBalance = Balance FROM inserted
SELECT @CustNo = CustNo FROM inserted
INSERT INTO AuditTrailCustomerBalance( TimeChanged, ChangedBy, OldBalance, NewBalance, CustNo )
VALUES( GETDATE(), SUSER_SNAME(), @OldBalance, @NewBalance, @CustNo )
END
END
GO
以及测试语句:
INSERT INTO Custs( CustNo, GivenName, Surname, DOB, SIN )
VALUES( 1, 'Peter', 'Griffen', 'January 15, 1950', '555555555')
INSERT INTO Accounts( CustNo, Type, Balance, AccruedInt, WithdrawalCount )
VALUES( 1, 'Savings', 0, 0, 0 )
UPDATE Accounts SET Balance = 100
WHERE CustNo = 1
【问题讨论】:
-
你的触发器坏了。您需要编写访问
inserted和deleted的基于 set 的查询,因为这些表可以包含 多个 行(或没有行),因此分配给标量变量将选择任意值(甚至不一定都来自同一行)。在单个UPDATE语句中,一些 行的余额可能发生了变化,而其他行可能没有。 -
好的,我对使用触发器还是新手,所以我应该使用 SET 而不是 SELECT 来分配变量,这就是你的意思?
-
不,我是说
SELECT @NewBalance = Balance FROM inserted存在根本缺陷,因为inserted可能包含 3 行 - 具有 3 个不同的余额值 - 但显然@NewBalance只能设置为等于 其中一个值。
标签: sql sql-server