SQL Server为每个修改的列创建审核

时间:2018-11-09 03:01:20

标签: sql sql-server

我想为每个修改的列创建sql服务器审核,但是我遇到了错误,这是我的代码:

BEGIN
  -- Type the SQL Here.
    DECLARE @event_type varchar(42)

    IF EXISTS(SELECT * FROM inserted)
        IF EXISTS(SELECT * FROM deleted)
            SELECT @event_type = 'U'
    ELSE
            SELECT @event_type = 'I'
    ELSE
        IF EXISTS(SELECT * FROM deleted)
            SELECT @event_type = 'D'
        ELSE
    --no rows affected - cannot determine event
    SELECT @event_type = 'UN'

    IF NEW.Code <> OLD.Code THEN  
        INSERT INTO CountryAuditTrail (Id, CountryId, Type, Field, OldValue, NewValue, CreatedAt, CreatedBy) 
        VALUES (NEWID(), Old.Id, @event_type, 'Code', Old.Code, New.Code, NEW.ModifiedAt, NEW.ModifiedBy);

    IF NEW.Name <> OLD.Name THEN  
        INSERT INTO CountryAuditTrail (Id, CountryId, Type, Field, OldValue, NewValue, CreatedAt, CreatedBy) 
        VALUES(NEWID(), Old.Id, @event_type, 'Name', Old.Name, New.Name, NEW.ModifiedAt, NEW.ModifiedBy);

    IF NEW.Status <> OLD.Status THEN  
        INSERT INTO CountryAuditTrail (Id, CountryId, Type, Field, OldValue, NewValue, CreatedAt, CreatedBy) 
        VALUES(NEWID(), Old.Id, @event_type, 'Status', Old.Status, New.Status, NEW.ModifiedAt, NEW.ModifiedBy);
END

我从其他stackoverflow解决方案中获得了此NEWOLD,但是它不起作用。错误是:

  

THEN附近的语法不正确

如何解决这个问题?

因此它可以将插入或更新的列中的每一列记录到审计跟踪表中


我要实现的是使用触发器记录指定的修改列。

Country表中,我仅指定到CodeNameStatus

插入触发器:

为每个代码,名称和状态插入表CountryAudit

更新触发器:

检查old.codenew.code是否不同,如果不同,则插入CountryAudit

和其他列

2 个答案:

答案 0 :(得分:2)

您的代码不是在SQL Server中编写触发器的正确​​方法。您需要意识到inserteddeleted可以有多于一行。

因此,您需要使用设置操作。

如果我正确地遵循了逻辑,那么您想要这样的事情:

begin
    insert into CountryAuditTrail (Id, CountryId, Type, Field, OldValue, NewValue, CreatedAt, CreatedBy) 
        select newid(), coalesce(i.id, d.id),
               (case when i.id is null then 'D'
                     when d.id is null then 'I'
                     else 'U'
                end),
               v.col, v.oldvalue, v.newvalue,
               i.ModifiedAt, i.ModifiedBy
        from inserted i full join
             deleted d
             on i.id = d.id cross apply
             (values ('code', i.code, d.code),
                     ('name', i.name, d.name),
                     ('status', i.status, d.status)
             ) v(col, newvalue, oldvalue)
        where oldvalue <> newvalue or
              (oldvalue is null and newvalue is not null) or
              (oldvalue is not null and newvalue is null);
end;

答案 1 :(得分:0)

您的语法错误

使用此语法

IF `condition` BEGIN
   statement;
END