外键审计触发器

时间:2020-08-15 11:03:02

标签: sql-server tsql triggers audit

以下代码是我的Branch表的审核触发器。它可以记录Branch表中的任何编辑或插入更改。

但是,我有一个BranchZoneID表的外键BranchZone。我要这样做,以便记录对该外键的任何更改,并显示BranchZoneName表中的BranchZone而不是BranchZoneID

我尝试使用代码来为外键属性BranchZoneID创建触发器。但是,我无法为其创建有效的触发器。

BranchZoneID的触发器不起作用。我需要更改什么?

create trigger Branch_Audit
on dbo.Branch
after insert, update
not for replication
as
begin
  set nocount on;

  declare @operation char(10) = case when exists (select * from deleted) then 'Edit' else 'Insert' end;

  insert AuditLog
(TableName, ModifiedBy, AuditDateTime, AuditAction, ID, ChangedColumn, OldValue, NewValue)
    select
      'Branch', suser_sname(), getdate(), @operation, I.BranchZoneID,
      'BranchName', convert(varchar(21),D.BranchName), convert(varchar(21),I.BranchName)
    from inserted I
    left outer join deleted D on I.BranchID = D.BranchID
    where coalesce(I.BranchName,'') <> coalesce(D.BranchName,'')
    and update(BranchName)
    union all

    select
    'Branch', suser_sname(), getdate(), @operation, I.BranchID,
    'BranchAddress', D.BranchAddress, I.BranchAddress
    from inserted I
    left outer join deleted D on I.BranchID = D.BranchID
    where coalesce(I.BranchAddress,'') <> coalesce(D.BranchAddress,'')
    and update(BranchAddress)
    union all


    select
    'Branch', suser_sname(), getdate(), @operation, I.BranchID,
    'BranchGeoLocationLat', D.BranchGeoLocationLat, I.BranchGeoLocationLat
    from inserted I
    left outer join deleted D on I.BranchID = D.BranchID
    where coalesce(I.BranchGeoLocationLat,'') <> coalesce(D.BranchGeoLocationLat,'')
    and update(BranchGeoLocationLat)
    union all


    select
    'Branch', suser_sname(), getdate(), @operation, I.BranchID,
    'BranchGeoLocationLong', D.BranchGeoLocationLong, I.BranchGeoLocationLong
    from inserted I
    left outer join deleted D on I.BranchID = D.BranchID
    where coalesce(I.BranchGeoLocationLong,'') <> coalesce(D.BranchGeoLocationLong,'')
    and update(BranchGeoLocationLong)
    union all

    select
    'Branch', SUSER_SNAME(), GETDATE(), @operation, I.BranchID,
    'BranchZoneID', OWD.BranchZoneName, NWD.BranchZoneName
    from inserted I
    left outer join deleted D on I.BranchID = D.BranchID
    where coalesce(I.BranchZoneID,'') <> coalesce(D.BranchZoneID,'')
    and update(BranchZoneID)
    -- Fetch Branch Zone Name
    on deleted.BranchZoneID = OWD.BranchZoneID
    join dbo.BranchZone NWD
    on inserted.BranchZoneID = NWD.BranchZoneID

end;

1 个答案:

答案 0 :(得分:1)

您只是对您的联接感到困惑...正确地联接,它可以按预期工作。请记住,使用表格别名时,您只能从那时起使用别名来引用表格。 I而不是Inserted

还要假设BranchZoneIDint,则需要coalesce到未使用的int,例如0不是一个空字符串。

select
    'Branch', suser_sname(), getdate(), @operation, I.BranchID
    , 'BranchZoneID', OWD.BranchZoneName, NWD.BranchZoneName
from inserted I
left outer join deleted D on I.BranchID = D.BranchID

-- Fetch Branch Zone Names
left join dbo.BranchZone OWD on OWD.BranchZoneID = D.BranchZoneID
left join dbo.BranchZone NWD on NWD.BranchZoneID = I.BranchZoneID

where coalesce(I.BranchZoneID,0) <> coalesce(D.BranchZoneID,0)
and update(BranchZoneID);

如果BranchZoneIDuniqueidentifer,则可以使用:

where coalesce(I.BranchZoneID,'00000000-0000-0000-0000-000000000000') <> coalesce(D.BranchZoneID,'00000000-0000-0000-0000-000000000000')

使用coalesce以这种方式比较值时,您需要选择一个对数据类型有效但在数据中无效的值。

相关问题