如何确定t-sql中更新触发器中是否有任何更改

时间:2012-05-11 11:15:14

标签: sql-server tsql triggers

如何在UPDATE触发器中确定某些内容是否已更改?例如,我有一个名为person的表,只有一列NAME,其中包含值'Mike'。如果我跑

UPDATE person SET NAME = 'Mike' 

如何在更新触发器中确定没有任何更改?我知道     UPDATE(COL) 声明,但我不想迭代列。有没有其他方法可以实现这个目标?

2 个答案:

答案 0 :(得分:36)

更新(列)仅表示该列参与了更新,但并未表明其值已更改。例如,

update Person SET Name = Name

在更新(名称)中产生true,即使名称在任何行中都没有更改。

要检查新值是否与旧值不同,您可以使用except,因为除了将从底部集合中存在的顶部集合中删除行。由于人员表可能具有主键,因此不存在删除已删除的对应项的更改项的危险。但是,如果您决定将*更改为有趣列的列表,请确保包含主键。

insert into logTable (ID)
select a.ID
from
(
   select * from Inserted
   except
   select * from Deleted
) a

额外的好处是,这也适用于插入,因为Deleted将为空,并且将返回插入的所有行。

答案 1 :(得分:18)

参考Arion上面的回答:

确保在从JOIN中选择时通过主键比较记录,因为INSERTED和DELETED表可能包含多个记录,如果忽略这些记录,可能会导致错误的查询结果和对DB性能的负面影响。

-- Anrion's answer - slightly modified
CREATE TRIGGER UpdatedTriggerName
ON person -- table name
AFTER UPDATE
AS 
IF EXISTS (
    SELECT
        *
    FROM
        INSERTED I
        JOIN
        DELETED D
            -- make sure to compare inserted with (same) deleted person
            ON D.ID = I.ID 
            AND D.NAME <> I.NAME -- only persons with changed name
    )
print 'something'
GO