Cha*_*ace 5 sql-server delete t-sql merge derived-tables
首先,可更新的 CTE、派生表或视图可以直接作为目标UPDATE
,即使它具有多个基表,只要所有列都来自同一源表。
DELETE
但即使仅选择一个表中的列,它们也不能成为 a 的目标。
Msg 4405 Level 16 State 1
View or function 'x' is not updatable because the modification affects multiple base tables.
Run Code Online (Sandbox Code Playgroud)
为了绕过这个限制,我尝试MERGE
对虚拟表使用 a 。(显然,这个简单的示例可以使用DELETE...WHERE EXISTS
或通过将一个表作为合并源来编写,但这一点是正确的。使用了原始示例,ROW_NUMBER
因此这些是不可能的。)
WITH Joined AS (
SELECT t1.*
FROM t1
JOIN t2 ON t2.id1 = t1.id1
)
MERGE Joined
USING (VALUES(0)) v(dummy) ON 1=0
WHEN NOT MATCHED BY SOURCE THEN DELETE;
Run Code Online (Sandbox Code Playgroud)
这实际上是被允许的。但我发现被修改的表并不依赖于所选择的列或其顺序。这完全取决于表的连接顺序。
在我看来,这似乎是完全错误的行为。
实验THEN UPDATE
显示了更明智的行为:它取决于子句中使用的列THEN UPDATE
,与普通语句相同UPDATE
。
所以,我认为 SQL Server 应该:
UPDATE
),以确保没有歧义。THEN DELETE
完全不允许。MERGE
我对可更新视图的工作方式是否有一些误解,或者这里是否存在实际错误?
现已在 Azure 反馈上提交错误报告。请在这里投票。
从一方面来看,你的问题是无法回答的,因为这取决于MERGE
设计意图。文档中没有任何内容可以明确解决这种情况。
我的观点是,它的MERGE
行为应该与非选项相同MERGE
;也就是说DELETE
应该被禁止。
table_or_view_name
要从中删除行的表或视图的名称。表变量在其范围内也可以用作
DELETE
语句中的表源。table_or_view_name引用的视图必须是可更新的,并且在视图定义的子句中恰好引用一个基表
FROM
。
(强调已添加)
这里不会产生错误的事实MERGE
可能是因为解析器很难检测到条件。或者这是一种疏忽,正如变化的异常复杂性所常见的那样MERGE
。
无论如何,我的立场是,在找到“有效”的方法之前,您应该避免解决不允许的行为。或者,您不应该对任何奇怪或不确定的结果感到惊讶。
将该问题作为错误报告给 Microsoft,以便他们进行调查。
归档时间: |
|
查看次数: |
254 次 |
最近记录: |