27

如何确定 UPDATE 触发器中是否发生了变化?例如,我有一个名为 person 的表,其中只有一列 NAME,其中包含值“Mike”。如果我跑

UPDATE person SET NAME = 'Mike' 

如何在更新触发器中确定没有任何变化?我知道 UPDATE(col) 语句,但我不想遍历列。有没有其他方法可以做到这一点?

4

2 回答 2

46

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

update Person SET Name = Name

在 update(name) 中产生 true,即使 Name 在任何行中都没有更改。

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

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

另一个好处是这也适用于插入,因为 Deleted 将是空的,并且插入的所有行都将被返回。

于 2012-05-11T13:12:08.727 回答
24

参考上面 Arion 的回答:

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

-- 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
于 2013-09-24T16:12:04.613 回答