Zik*_*ato 5 trigger sql-server merge
有时为了重构,我使用视图来抽象更改并使用INSTEAD OF触发器来模仿以前的功能。
我过去遇到过错误 414(或 415)
不允许 UPDATE,因为该语句更新参与联接并具有 INSTEAD OF UPDATE 触发器的视图“%.*ls”。
我可以将其重写UPDATE FROM为MERGE语句并且有效。但为什么?
我找到了这些参考资料,但没有一个能回答原因。
https://sqlserverfast.com/blog/hugo/2008/03/lets-deprecate-update-from/
我的理解是这是不允许的,因为UPDATE...FROM由于向后兼容性而保留了一些奇怪的行为。当视图具有替代触发器时,使这些工作相同将是困难的,也许是不可能的。
MERGE有几个弱点,但它确实具有明确定义和合理的更新语义。
主要的示例是MERGE防止不明确的更新\xe2\x80\x94,其中目标行被 SQL 规范逻辑更改多次。如果模式中没有任何内容绝对保证目标行不能被多次修改,则MERGE计划会引入运算符在运行时检查此条件,并在遇到时引发错误。
这使得使用替代MERGE触发器在目标上实现连接表变得更容易/完全可能。
UPDATE...FROM当目标表被多次引用时,该语法还具有奇怪的绑定行为(再次维护以避免破坏旧代码),有时通过别名,有时不引用。
与您的问题没有直接关系,但文档中有一个带有 CTE 的边缘情况示例:
\n\n\n当公用表表达式 (CTE) 是 UPDATE 语句的目标时,语句中对 CTE 的所有引用都必须匹配。例如,如果在 FROM 子句中为 CTE 分配了一个别名,则该别名必须用于对该 CTE 的所有其他引用。需要明确的 CTE 引用,因为 CTE 没有对象 ID,而 SQL Server 使用对象 ID 来识别对象与其别名之间的隐式关系。如果没有这种关系,查询计划可能会产生意外的联接行为和意外的查询结果。
\n
尽管如此,仅仅因为它可以工作MERGE并不意味着没有潜伏的错误。有关半相关示例,请参阅使用 INSTEAD OF 触发器合并到视图中。
努力推动复杂功能组合的边缘是发现边缘情况错误的好方法。
\n