T-SQL MERGE:这种模式可能吗?:如果标志为真则INSERT(一次)或如果标志为假则为DELETE

时间:2014-06-25 23:05:08

标签: sql sql-server tsql merge

我希望使用单个SQL语句(即“MERGE”)来管理表示数学集的表:如果为true,则插入元素,否则删除。

以冰淇淋为例,我想根据下面的@Exist标志添加一个风味或从列表中删除一个风味。这可能吗?我已经玩了几个小时了,要么它在语法上是正确的,并且不插入行或者我编写查询来执行我认为需要完成的操作但是由于语法无效而无法编译。 (MSDN MERGE "man" page)

这是我的可行尝试:

CREATE TABLE IceCream(
    Flavor VARCHAR(50) NOT NULL,
    CONSTRAINT AK_Flavor UNIQUE(Flavor)
)

DECLARE @Flavor varchar(50)
DECLARE @Exist bit

set @Flavor='Vanilla'
set @Exist=1

MERGE IceCream AS T
USING IceCream AS S
ON S.Flavor=T.Flavor AND
    S.Flavor=@Flavor AND
    T.Flavor=@Flavor
WHEN NOT MATCHED BY TARGET AND @Exist=1
    THEN INSERT (Flavor) VALUES (@Flavor)
WHEN NOT MATCHED BY SOURCE AND @Exist=0
    THEN DELETE
OUTPUT $action, inserted.*, deleted.*;

1 个答案:

答案 0 :(得分:1)

虽然有不同的方法可以实现您的目标,但这个MERGE语句可以正常运行:

DECLARE @Flavor varchar(50), @Exist bit;

SET @Flavor = 'Orange';
SET @Exist  = 1;

;WITH TGT AS (SELECT Flavor FROM IceCream WHERE Flavor = @Flavor)
MERGE INTO TGT
USING (VALUES(@Flavor, @Exist)) AS SRC(Flavor, Exist)
   ON TGT.Flavor = SRC.Flavor
WHEN MATCHED AND SRC.Exist = 0
     THEN DELETE
WHEN NOT MATCHED BY TARGET AND SRC.Exist = 1
     THEN INSERT (Flavor) VALUES (SRC.Flavor);

从初始列表开始:

INSERT INTO IceCream VALUES ('Vanilla'), ('Chocolate'), ('Strawberry')  

用几个不同的对进行测试(Flavor,Exist):

[Orange,1]
----------
Chocolate, Orange, Strawberry, Vanilla

[Rasberry,0]
----------
Chocolate, Orange, Strawberry, Vanilla

[Vanilla,0]
----------
Chocolate, Orange, Strawberry

[Chocolate,1]
----------
Chocolate, Orange, Strawberry    

[Java,1]
----------
Chocolate, Java, Orange, Strawberry

<强>简化:

实际上,我使用CTE作为目标,因为你的原始示例有WHEN NOT MATCHED BY SOURCE THEN DELETE,十分之九,当同步一个集时,你的目标需要被一个子查询约束(在这种情况下是一个CTE) MERGE)。

但是,您的实际需求似乎不需要WHEN NOT MATCHED BY SOURCE子句,因此您可以使用相同的结果简化上述语句:

;MERGE INTO IceCream AS TGT
USING (VALUES(@Flavor, @Exist)) AS SRC(Flavor, Exist)
   ON TGT.Flavor = SRC.Flavor
WHEN MATCHED AND SRC.Exist = 0
     THEN DELETE
WHEN NOT MATCHED BY TARGET AND SRC.Exist = 1
     THEN INSERT (Flavor) VALUES (SRC.Flavor);