我想写一个触发器来执行某些逻辑,除非只更新了一个特定的列,例如如果仅更新了'UpdateDate'列,则不要打扰触发器。
我知道我可以使用UPDATE()和COLUMNS_UPDATED(),但似乎很难以可维护的方式编写它以检查是否只更新了一列。例如。我可以对表中的每个其他列调用UPDATE(),但如果有人添加了另一列而没有修改触发器,它将会中断。
答案 0 :(得分:2)
对于SQL Server 2005+,我会这样做:
假设Column4
是您要忽略的特定列,我会这样做:
select *
into #changedRows
from (
select Column1, Column2, Column3 from deleted
except
select Column1, Column2, Column3 from inserted
) x
if not exists (select * from #changedRows)
return;
这种方法的优点在于,它不仅可以正确地确定列是否已更新,还可以正确确定数据是否实际已更改,这通常是您所关心的。
答案 1 :(得分:1)
我最终提出了这个逻辑:
如果
然后不要触发其余的触发器。
e.g。
-- If columns_updated() is bigger than a bigint will take then
-- just continue. We could deal with this better but not an issue for me.
if datalength(columns_updated())<63 begin
declare @colsUpdated bigint
set @colsUpdated = cast( columns_updated() as bigint )
-- if UpdateDate column was updated AND there was only a single column updated
-- don't run the rest of the trigger. See http://stackoverflow.com/a/4624295/8479
-- for discussion of how to check if only one bit of a number is set. If only
-- one bit is set then only one col was updated, and we use update() to check
-- if it was UpdateDate.
if update(UpdateDate)
and ( @colsUpdated & ( @colsUpdated-1 ) = 0 )
begin
return;
end
end