Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在更新触发器中查找修改的字段_Sql_Sql Server_Tsql_Triggers_Sql Server 2008 R2 - Fatal编程技术网

Sql 在更新触发器中查找修改的字段

Sql 在更新触发器中查找修改的字段,sql,sql-server,tsql,triggers,sql-server-2008-r2,Sql,Sql Server,Tsql,Triggers,Sql Server 2008 R2,获取更新触发器中所有修改字段列表的最简单方法是什么 我能想到的最简洁的方法就是做这样的事情: IF EXISTS(SELECT 1 FROM INSERTED INNER JOIN DELETED ON INSERTED.[FIELD_TO_CHECK] = DELETE.[FIELD_TO_CHECK]) 但这意味着我必须对我想检查的每个领域都这样做。我希望使用光标包含所有修改字段的信息 (批量更新不需要这样做,插入的或删除的中不需要超过1条记录) 我添加了一个if语句来忽略批量更新,因为它

获取
更新触发器中所有修改字段列表的最简单方法是什么

我能想到的最简洁的方法就是做这样的事情:

IF EXISTS(SELECT 1 FROM INSERTED INNER JOIN DELETED ON INSERTED.[FIELD_TO_CHECK] = DELETE.[FIELD_TO_CHECK])
但这意味着我必须对我想检查的每个领域都这样做。我希望使用
光标
包含所有修改字段的信息


(批量更新不需要这样做,插入的
或删除的
中不需要超过1条记录)


我添加了一个if语句来忽略批量更新,因为它们属于不同的类别。

不幸的是,我不知道有任何可靠的内置函数可以指示当update语句触发触发器时,列的值是否实际发生了更改

但是,您可以执行非常简单的select语句来查看哪些行中的值发生了更改:

SELECT IIF(ISNULL(NULLIF(I.Col, D.Col), NULLIF(D.Col, I.Col)) IS NULL, 0, 1) As Col_Updated
FROM Inserted I
JOIN Deleted D
    ON I.PrimaryKey = D.PrimaryKey
如果两列相等,则
NULLIF
函数将返回
null
。如果不是,则返回第一列的值

ISNULL
函数将返回不是
null
的第一个参数,如果两个参数都为null,则返回
null

对两个列值颠倒的
null
函数的结果使用
ISNULL
将导致
null
如果两个列的值相同,即使它们都为null。如果值不同,即使其中一个为null,另一个为null,则
ISNULL
将返回一个值。因此,您所要做的就是检查
ISNULL
是否返回值或null-如果它返回
null
,您就知道列的值没有更改。如果它返回一个值,那么它将被更改

当然,对于不可为空的列,可以简化如下条件:

SELECT IIF(I.Col <> D.Col, 1, 0) As Col_Updated
FROM...
此方法依赖于这样一个事实:将null与任何其他内容进行比较将导致
未知
,这基本上等同于


IMHO的可读性稍高。

“插入或删除的记录不需要超过1条”,直到您得到该记录为止。。。最好不要假设这样的假设。当你发现更新了哪些列时,你的实际目标是什么?如果只需要记录旧值,那么通常只需记录整行,即是否更新了1列或100列。否则,可能会重复?如果您不希望获得多行,并且不打算正确处理多行,那么触发器应该在遇到多行时抛出错误来强制执行此假设。为什么?因为总有一天会发生的。如果你想用光标进行处理,为什么不写一个呢?@TabAlleman我在问是否有办法用光标选择所有修改过的字段,并对每个字段执行特定的操作
IIF((I.Col IS NULL AND D.Col IS NULL) OR (I.Col = D.Col), 0, 1) as IsUpdated.