Sql server 更新时不会为所有行触发触发器(随机)
我创建了一个触发器来捕获副本表中的所有插入、更新和删除操作,但在更新的情况下,插入了两行,一行具有更新前的值,另一行具有更新后的值,但它没有按预期工作 我已经尝试了所有可能的方法来做这件事。现在,我想知道是应该在触发器级别使用事务进行更新操作,还是应该尝试其他操作Sql server 更新时不会为所有行触发触发器(随机),sql-server,tsql,database-trigger,Sql Server,Tsql,Database Trigger,我创建了一个触发器来捕获副本表中的所有插入、更新和删除操作,但在更新的情况下,插入了两行,一行具有更新前的值,另一行具有更新后的值,但它没有按预期工作 我已经尝试了所有可能的方法来做这件事。现在,我想知道是应该在触发器级别使用事务进行更新操作,还是应该尝试其他操作 ALTER TRIGGER [dbo].[trgAfterInsertUpdateDelete_xyz] ON [dbo].[xyz] FOR UPDATE,INSERT, DELETE AS declare @accountID
ALTER TRIGGER [dbo].[trgAfterInsertUpdateDelete_xyz] ON [dbo].[xyz]
FOR UPDATE,INSERT, DELETE
AS
declare @accountID int;
declare @billingDate date;
declare @amount decimal(18, 2);
---- Get data from inserted/ updated
select @accountID = i.AccountID from inserted i;
select @billingDate=i.BillingDate from inserted i;
select @amount=i.Amount from inserted i;
-- Insert Case
IF EXISTS( SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
insert into xyz_Audit
(AccountID, BillingDate, Amount, Audit_Action)
values(@accountID,@billingDate,@amount,'INSERT');
END
-- Update Case
IF EXISTS( SELECT * FROM inserted) AND EXISTS(SELECT * FROM deleted)
BEGIN
INSERT INTO xyz_Audit
(AccountID, BillingDate, Amount, Audit_Action)
SELECT d.AccountID, d.BillingDate, d.Amount,
'BeforeUpdate' FROM Inserted i
INNER JOIN Deleted d ON i.ID = d.ID
INSERT INTO xyz_Audit
(AccountID, BillingDate, Amount,Audit_Action)
values(@accountID,@billingDate,@amount,'AfterUpdate');
END
-- Delete Case
IF EXISTS( SELECT * FROM deleted) AND NOT EXISTS(SELECT * FROM inserted)
BEGIN
INSERT INTO xyz_Audit
(AccountID, BillingDate, Amount, Audit_Action)
select accountID,billingDate,amount, 'DELETE'
from deleted
END
我希望如果更新了9条记录,那么所有行都应该有更新前后的值,但有时会跳过。如您所见,对于Inst.8,应该有前后两行,但它只捕获了前一行,然后插入,但实际上并没有删除和插入行,只进行了更新。有时在9行中,它只在更新行之前而不是更新行之后拾取,有时在更新行之后而不是更新行之前拾取2或3行。您的触发器假定插入/更新/删除操作只影响一行。这意味着插入的
或删除的可能包含多行
下面的部分不处理这个问题
---- Get data from inserted/ updated
select @accountID = i.AccountID from inserted i;
select @billingDate=i.BillingDate from inserted i;
select @amount=i.Amount from inserted i;
事实上,你根本不需要以上这些。您应该直接从插入的或删除的表中插入审计表
例如,“插入案例”
应该是
-- Insert Case
IF EXISTS( SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
insert into xyz_Audit (AccountID, BillingDate, Amount, Audit_Action)
select AccountID, BillingDate, Amount, Audit_Action= 'INSERT'
from inserted;
END
同样,您需要对更新部分进行相应的更改。假设插入/更新/删除操作只影响一行,那么对于删除部分,您已经正确地执行了该操作。这意味着插入的或删除的可能包含多行
下面的部分不处理这个问题
---- Get data from inserted/ updated
select @accountID = i.AccountID from inserted i;
select @billingDate=i.BillingDate from inserted i;
select @amount=i.Amount from inserted i;
事实上,你根本不需要以上这些。您应该直接从插入的或删除的表中插入审计表
例如,“插入案例”
应该是
-- Insert Case
IF EXISTS( SELECT * FROM inserted) AND NOT EXISTS(SELECT * FROM deleted)
BEGIN
insert into xyz_Audit (AccountID, BillingDate, Amount, Audit_Action)
select AccountID, BillingDate, Amount, Audit_Action= 'INSERT'
from inserted;
END
同样,您需要对更新部分进行相应的更改。您已经正确地完成了删除部分的操作ok谢谢您的回复。你100%确信这是唯一的问题。现在,无论何时更新9行或18行,它都会捕获所有行的前后行。因为有时它以适当的方式工作,有时又不是一件事,触发器的第二次更新部分是否需要事务?它是按顺序插入数据还是随机插入数据?表示指令1同时具有前后行或以某种随机方式,它将按照您的insert语句的顺序。谢谢@squirrel在尝试一段时间后,如果数据捕获中没有出现错误,它肯定会接受作为答案。非常感谢uOkk的回复。你100%确信这是唯一的问题。现在,无论何时更新9行或18行,它都会捕获所有行的前后行。因为有时它以适当的方式工作,有时又不是一件事,触发器的第二次更新部分是否需要事务?它是按顺序插入数据还是随机插入数据?表示指令1同时具有前后行或以某种随机方式,它将按照您的insert语句的顺序。谢谢@squirrel在尝试一段时间后,如果数据捕获中没有出现错误,它肯定会接受作为答案。非常感谢你