代码之家  ›  专栏  ›  技术社区  ›  nick zoum

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

  •  0
  • nick zoum  · 技术社区  · 5 年前

    最简单的方法是什么来获取 Update Trigger ?

    我能想到的最紧凑的方法是做这种类型的事情:

    IF EXISTS(SELECT 1 FROM INSERTED INNER JOIN DELETED ON INSERTED.[FIELD_TO_CHECK] = DELETE.[FIELD_TO_CHECK])
    

    但这意味着我必须为我想要检查的每个字段都这样做。我会很感激 cursor 包含有关所有已修改字段的信息。

    (这不需要进行批量更新,不需要在 INSERTED DELETED )

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

    1 回复  |  直到 5 年前
        1
  •  1
  •   Zohar Peled    5 年前

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

    但是,有一个非常简单的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 函数将返回第一个不是 无效的 无效的 如果两个参数都为空。

    使用 无空 关于二的结果 努利夫 列值反转的函数将导致 无效的 如果两列的值相同,即使它们都为空。如果值不同,即使其中一个值为空,而另一个值不是,则 无空 将返回一个值。因此,你所要做的就是检查 无空 返回值或空值-如果返回 无效的 ,您知道列的值没有更改。如果它返回一个值,那么它将被更改。

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

    SELECT IIF(I.Col <> D.Col, 1, 0) As Col_Updated
    FROM...
    

    不过我还是建议你 反对 这是因为,如果有人将列更改为允许空,则触发器代码必须更改以支持这一点——根据我的经验,这是一个等待发生的错误——触发器代码可能不会更改,从而导致错误否定。

    You can see a live demo on rextester.