Sql server TSql触发器只需在值已更改的列上触发

Sql server TSql触发器只需在值已更改的列上触发,sql-server,tsql,triggers,Sql Server,Tsql,Triggers,我编写了一个触发器,需要根据行中的哪些列实际更新,对表执行一些不同的工作。我是用 IF UPDATE(column-name) 那部分很好用。然而,事实证明,代码的其他部分通过设置每个值来更新行,无论值是否实际更改,这会导致触发器为已更新但其值根本没有更改的部分触发 由于更改导致此问题的代码可能不是一个选项,除了必须在插入的表和删除的表之间进行比较(在这种情况下,IF更新没有意义)之外,还有更简单的方法来防止此问题吗?据我所知。插入和删除是有原因的,对我来说,比较它们似乎是最好的选择 IF U

我编写了一个触发器,需要根据行中的哪些列实际更新,对表执行一些不同的工作。我是用

IF UPDATE(column-name)
那部分很好用。然而,事实证明,代码的其他部分通过设置每个值来更新行,无论值是否实际更改,这会导致触发器为已更新但其值根本没有更改的部分触发

由于更改导致此问题的代码可能不是一个选项,除了必须在插入的表和删除的表之间进行比较(在这种情况下,IF更新没有意义)之外,还有更简单的方法来防止此问题吗?

据我所知。插入和删除是有原因的,对我来说,比较它们似乎是最好的选择


IF UPDATE只告诉您是否进行了插入或更新尝试,甚至不反映该尝试是否成功。

该列已更新。旧值和新值相同只是一个细节。我认为您唯一的解决方案是比较插入和删除的伪表之间的值。

正如其他人所说,您必须使用插入和删除的表

以下是我所做的,而不是:

IF UPDATE(col1) OR UPDATE(col2))
UPDATE table1
SET col3 = 1
FROM INSERTED
WHERE table1.Id = INSERTED.Id
我已经做了:

IF UPDATE(col1) OR UPDATE(col2))
 UPDATE table1
 SET col3 = 1
 FROM 
  (SELECT Id, col1, col2 FROM INSERTED 
   EXCEPT 
  SELECT Id, col1, col2 FROM DELETED) AS ALTERED
 WHERE table1.Id = ALTERED.Id
使用EXCEPT选择我感兴趣的列在已删除或原始数据表中不存在的不同行,这意味着这些列的值已更改。我不知道这是否是最好的答案,但它似乎确实有效

IF EXISTS (SELECT *
          FROM
             INSERTED I JOIN DELETED D ON I.Key = D.Key
          WHERE
             I.Col <> D.Col)
...
或者使用表变量进行缓存,从而避免重复使用I和D

SELECT
    CASE WHEN I.Col1 <> D.Col1 THEN 1 ELSE 0 END AS Col1Diff,
    CASE WHEN I.Col2 <> D.Col2 THEN 1 ELSE 0 END AS Col2Diff,
    ...
FROM
    INSERTED I JOIN DELETED D ON I.Key = D.Key
或者结合想法预先测试所有更改并退出触发器