如何在UPDATE触发器中确定某些内容是否已更改?例如,我有一个名为person的表,只有一列NAME,其中包含值'Mike'。如果我跑
UPDATE person SET NAME = 'Mike'
如何在更新触发器中确定没有任何更改?我知道 UPDATE(COL) 声明,但我不想迭代列。有没有其他方法可以实现这个目标?
答案 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