使用多个WHEN MATCHED语句时,是全部执行,还是只执行一个?

问题描述 投票:0回答:3

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

四种可能性中 X 的状态是什么?

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

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

sql sql-server t-sql merge
3个回答
25
投票

回答你的问题,是的,它只会运行一场比赛,然后就中断。 但是,如果您希望拥有允许在更新中进行条件匹配的逻辑,则

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

25
投票

我在MSDN文档中找到:

当匹配时

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

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

所以看起来只执行了其中一条语句,并且它们需要在一条语句中执行 DELETE,在另一条语句中执行 UPDATE。


1
投票

好吧,答案是,你真的想要吗?因为如果你这样做,你会通过令人痛苦的缓慢行更新来更改对行的基于集的更新,就像在一组行中一样,你真的不知道逐条记录更改了哪些列基础。

因此,问题是你想获得性能吗?如果是这样,请确保您的索引覆盖了

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

如果没有,您将不得不在合并后使用

INSTEAD OF
触发器将光标悬停在更新上...

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

快乐编码

沃尔特

© www.soinside.com 2019 - 2024. All rights reserved.