2012-03-01 81 views
0

我只希望将对ProjectID所做的更改传递到审计表。如果例如进行了更改,但阀门保持不变,则记录不会添加到审计表中。触发器只传递审计表的实际更改

CREATE TRIGGER trgAfterUpdate ON [dbo].[Assets] 
FOR UPDATE 
AS 
    declare @assetid int; 
    declare @assetname nvarchar(max); 
    declare @projectid int; 
    declare @audit_action varchar(100); 

    select @assetid=i.AssetID from inserted i; 
    select @assetname=i.AssetName from inserted i; 
    select @projectid=i.ProjectID from inserted i; 

    if update(ProjectID) 
     set @audit_action='Updated Record -- After Update Trigger.'; 

    insert into Asset_Test_Audit(AssetID,AssetName,Projectid,Audit_Action,Audit_Timestamp) 
    values(@assetid,@assetname,@projectid,@audit_action,getdate()); 

    PRINT 'AFTER UPDATE Trigger fired.' 
GO 
+0

你在哪个RDBMS上?请添加标签。 – vulkanino 2012-03-01 07:21:32

+0

你可以使用'INSTEAD OF'触发器,因为MS SQL没有'BEFORE'触发器。 – vulkanino 2012-03-01 07:29:01

回答

0

你必须与已删除的表像下面从插入表中的结果比较:

CREATE TRIGGER trgAfterUpdate ON [dbo].[Assets] 
FOR UPDATE 
AS 
declare @assetid int; 
declare @assetname nvarchar(max); 
declare @projectid int; 
declare @audit_action varchar(100); 

select @assetid=i.AssetID from inserted i; 
select @assetname=i.AssetName from inserted i; 
select @projectid=i.ProjectID from inserted i; 

if update(ProjectID) and exists (select * from deleted 
     where AssetID<>@assetid or AssetName<>@assetname or ProjectID<>@projectid) 
begin 
    set @audit_action='Updated Record -- After Update Trigger.'; 

insert into Asset_Test_Audit(AssetID,AssetName,Projectid,Audit_Action,Audit_Timestamp) 
values(@assetid,@assetname,@projectid,@audit_action,getdate()); 

PRINT 'AFTER UPDATE Trigger fired.' 
end 

GO 
+0

谢谢,效果很好 – user1240661 2012-03-01 10:02:49

0

您可能希望以不同的方式做到这一点。 inserted和deleted表持有的所有记录以前和当前状态更新,你需要审核他们都:

CREATE TRIGGER trgAfterUpdate ON [dbo].[Assets] 
AFTER UPDATE 
AS 
    set NoCount ON -- So that your insert does not mess with update rowcount 

    if update(ProjectID) 
    begin 
     insert into Asset_Test_Audit(AssetID, AssetName, Projectid, Audit_Action, Audit_Timestamp) 
     select AssetID, AssetName, ProjectID, 'Updated Record -- After Update Trigger.', getdate() 
      from Inserted 
      where not exists (select null from Deleted where Deleted.AssetID = Inserted.AssetID and Deleted.ProjectID = Inserted.ProjectID) 
    end  
    PRINT 'AFTER UPDATE Trigger fired.' 

GO 

几个要点:做数据恢复的一个选择;而不是三个,从插入的检索栏选择,使用一个:

select @assetid=i.AssetID, @assetname=i.AssetName, @projectid=i.ProjectID from inserted i; 

更新(columnName)方法并不意味着该列的该值已经改变,而只是说,它参与了更新:

update assets set ProjectID = ProjectID 
如果更新(ProjectID),

仍在返回true。

即使没有必要,也可以使用begin ..end,因为它可以为您节省头痛。可悲的是,你不会知道这个保存,但如果你不知道,你一定会知道(并感到痛苦)。