有时为了重构,我使用视图来抽象更改并使用INSTEAD OF
触发器来模仿以前的功能。
我过去遇到过错误 414(或 415)
UPDATE 是不允许的,因为语句更新了视图“%.*ls”,它参与了一个连接并且有一个 INSTEAD OF UPDATE 触发器。
我可以将其重写UPDATE FROM
为一个MERGE
语句并且有效。但为什么?
我找到了这些参考资料,但没有一个回答原因。
https://sqlserverfast.com/blog/hugo/2008/03/lets-deprecate-update-from/
我的理解是这是不允许的,因为
UPDATE...FROM
由于向后兼容性而保持了一些古怪的行为。当视图具有而不是触发器时,使这些工作相同是很困难的,也许是不可能的。MERGE
有几个弱点,但它确实具有定义明确且健全的更新语义。这方面的主要示例是
MERGE
防止模糊更新——目标行在逻辑上被 SQL 规范多次更改。如果模式中没有任何东西绝对保证不能多次修改目标行,则MERGE
计划引入操作员在运行时检查此条件,并在遇到时引发错误。这使得使用而不是触发器
MERGE
在目标上实现连接表更容易/完全可能。当
UPDATE...FROM
目标表被多次引用时,语法也有奇怪的绑定行为(再次维护以避免破坏旧代码),有时通过别名,有时不。与您的问题没有直接关系,但有一个文档中描述的带有 CTE 的边缘案例示例:
综上所述,仅仅因为它可以工作
MERGE
并不意味着没有潜伏的错误。有关半相关示例,请参阅MERGE into a view with INSTEAD OF triggers。在复杂特征组合的边缘努力是找到边缘情况错误的好方法。