当使用多个WHEN MATCHED语句时,它们都执行,还是只执行一个?

Cod*_*man 18 sql t-sql database sql-server merge

如果我在MERGE语句中有多个WHEN MATCHED语句,如果它们是真的,它们都会执行吗?

我的例子:

DECLARE @X bit = NULL;

--skipping the MERGE statement, straight to WHEN MATCHED

WHEN MATCHED AND A = 1
    @X = 0;
WHEN MATCHED AND B = 1
    @X = 1;
Run Code Online (Sandbox Code Playgroud)

在4种可能性中,X的状态是什么?

A|B|X
0|0|?
0|1|?
1|0|?
1|1|?
Run Code Online (Sandbox Code Playgroud)

基本上,我很好奇每个WHEN MATCHED条款后是否有隐含的BREAK.

Cod*_*man 18

我在MSDN文档中找到了:

当匹配时

指定target_table的所有行与ON返回的行匹配,并满足任何其他搜索条件,根据子句更新或删除.

MERGE语句最多可以有两个WHEN MATCHED子句.如果指定了两个子句,则第一个子句必须附带AND子句.对于任何给定的行,仅当第一个不是时才应用第二个WHEN MATCHED子句.如果有两个WHEN MATCHED子句,则必须指定UPDATE操作,并且必须指定DELETE操作.如果在子句中指定了UPDATE,并且多个匹配的行与target_table中的行匹配,则SQL Server会返回错误.MERGE语句不能多次更新同一行,或更新和删除同一行.

因此看起来只执行其中一个语句,它们需要一个DELETE而另一个需要UPDATE.


sge*_*des 17

要回答你的问题,是的,它只会运行一个匹配然后中断.但是,如果您希望在更新中允许条件匹配的逻辑,则该CASE语句对此非常有用.

像这样的例子:

MERGE INTO YourTable
USING (VALUES (1, 1, NULL), (0, 0, NULL), (0, 1, NULL), (1, 0, NULL))
       T2 (a2,b2,c2)
ON a = a2 AND b = b2
WHEN MATCHED  THEN
    UPDATE SET c = 
      CASE 
        WHEN a = 1 THEN 0
        WHEN b = 1 THEN 1
        ELSE NULL
      END        
WHEN NOT MATCHED THEN
    INSERT (a, b) VALUES (a2, b2);

SELECT * FROM YourTable ORDER BY a,b;
Run Code Online (Sandbox Code Playgroud)

结果如下:

A   B   C
--------------
0   0   (null)
0   1   1
1   0   0
1   1   0
Run Code Online (Sandbox Code Playgroud)