22

如果我在 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;

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

A|B|X
0|0|?
0|1|?
1|0|?
1|1|?

基本上,我很好奇每个 WHEN MATCHED 子句之后是否有隐式 BREAK 。

4

3 回答 3

22

我在MSDN 文档中找到:

当匹配然后

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

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

所以看起来只有一个语句被执行,它们需要一个 DELETE 和另一个 UPDATE。

于 2013-05-30T23:59:48.630 回答
21

要回答您的问题,是的,它只会运行一场比赛然后休息。但是,如果您希望在更新中具有允许条件匹配的逻辑,则该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;

结果:

A   B   C
--------------
0   0   (null)
0   1   1
1   0   0
1   1   0
于 2013-05-31T00:15:16.207 回答
1

好吧,答案是,你真的想要吗,因为如果你这样做了,你会通过痛苦的慢行更新来将基于集合的更新更改为行.

因此,问题是你想获得性能吗?如果是这样,请确保您有涵盖

WHEN MATCHED TARGET.FIELD1 = SOURCE:FIELD1 AND TARGET.FIELD2 = SOURCE:FIELD2 ... 

如果不是,您将不得不在合并后使用INSTEAD OF触发器将光标悬停在您的更新上......

不利于速度,但是,如果您需要记录谁做了什么,它可以工作......

快乐编码

沃尔特

于 2015-08-15T14:54:06.967 回答