Sql server 用于更新的T-SQL触发器审核

Sql server 用于更新的T-SQL触发器审核,sql-server,tsql,triggers,Sql Server,Tsql,Triggers,我需要执行一个更新触发器,以便将表位置的更改插入到审计表中 我知道如何访问插入/删除的新值和旧值,但我似乎找不到我需要做什么来获取已更新的不同列。我知道光标的使用等 这是我现在拿到的密码,是法文的 ALTER TRIGGER T_U_Locations ON Locations FOR UPDATE AS BEGIN --Definition des valeurs DECLARE @tempDuChangement VARCHAR(30); DECLARE @nomDuChampChang

我需要执行一个更新触发器,以便将表位置的更改插入到审计表中

我知道如何访问插入/删除的新值和旧值,但我似乎找不到我需要做什么来获取已更新的不同列。我知道光标的使用等

这是我现在拿到的密码,是法文的

ALTER TRIGGER T_U_Locations ON Locations
FOR UPDATE 
AS
BEGIN

--Definition des valeurs
DECLARE @tempDuChangement VARCHAR(30);
DECLARE @nomDuChampChange VARCHAR(64);
DECLARE @idLocation INT;
DECLARE @ancienneV VARCHAR(50);
DECLARE @nouvelleV VARCHAR(50);
DECLARE @raison VARCHAR(50);


--Aquisition des valeurs sur les changement apportés
SET @tempDuChangement = CONVERT( VARCHAR(30) , CURRENT_TIMESTAMP );

SET @nomDuChampChange = --HERE GOES THE CURRENT UPDATED COLUMN
SET @idLocation = (SELECT inserted.id FROM inserted);

SET @ancienneV = (SELECT /*HERE GOES THE CURRENT UPDATED COLUMN*/ FROM deleted);
SET @nouvelleV = (SELECT /*HERE GOES THE CURRENT UPDATED COLUMN*/ FROM inserted);

-- Crée une nouvelle entré dans la table Audits avec les information relative
INSERT INTO Audits
VALUES
(
    @tempDuChangement,
    @nomDuChampChange,
    @ancienneV,
    @nouvelleV,
    @idLocation,
    'raison test'
)
END
假设id是唯一的且在更新中未更改,我认为您需要:

insert into Audits (time, columnName, oldValue, newValue . . . )  -- always include the column list
    select Current_Timestamp, v.colname, v.oldValue, v.newValue, . . .
    from inserted i join
         deleted d
         on i.id = d.id outer apply
         (values ('col1', d.col1, o.col1),
                 ('col2', d.col2, o.col2),
                 ('col3', d.col3, o.col3),
                 . . .
         ) v(colname, oldValue, newValue)
     where v.oldValue <> v.newValue or
           v.oldValue is null and v.newValue is not null or
           v.oldValue is not null and v.newValue is null;
基本上,您是使用outerapply按列取消激活数据,因此需要包括所有列。where子句将获取已修改的id。

假设id是唯一的,并且在更新中没有更改,我认为您需要:

insert into Audits (time, columnName, oldValue, newValue . . . )  -- always include the column list
    select Current_Timestamp, v.colname, v.oldValue, v.newValue, . . .
    from inserted i join
         deleted d
         on i.id = d.id outer apply
         (values ('col1', d.col1, o.col1),
                 ('col2', d.col2, o.col2),
                 ('col3', d.col3, o.col3),
                 . . .
         ) v(colname, oldValue, newValue)
     where v.oldValue <> v.newValue or
           v.oldValue is null and v.newValue is not null or
           v.oldValue is not null and v.newValue is null;
基本上,您是使用outerapply按列取消激活数据,因此需要包括所有列。where子句将获取已修改的表。

请参阅:inserted和deleted是表,因此它们可以表示集合操作的结果。在假设触发器总是只处理一行的情况下设计触发器通常是一个糟糕的计划。如果您绝对确定不会有超过一行,那么请添加对行数的检查,并使用RaIsError或Throw显式通知稍后出现的人,他们试图执行不可接受的语句。如果选择Count*from inserted>1,则会出现错误“FooTable_Insert:最多只能处理一行”。、25、42以及LogReference:inserted和deleted是表,因此它们可以表示集合操作的结果。在假设触发器总是只处理一行的情况下设计触发器通常是一个糟糕的计划。如果您绝对确定不会有超过一行,那么请添加对行数的检查,并使用RaIsError或Throw显式通知稍后出现的人,他们试图执行不可接受的语句。如果选择Count*from inserted>1,则会出现错误“FooTable_Insert:最多只能处理一行”。、25、42以及日志