首页 > 解决方案 > 合并语句中的删除语句问题

问题描述

我正在处理merge into声明

我有一个看起来像这样的表(首先我像这样插入)使用下面的查询:

5 2
5 3
5 5
5 6

表类型:

CREATE TYPE [dbo].[userid] AS TABLE(
    [userid] [bigint] NULL
)
GO

现在我想要以下输出:

5 2
5 3
5 6

我这样写下面的查询:

--use test
declare @sid varchar(100) = '5'
declare @uid as userid

insert into @uid(userid) values(2)
insert into @uid(userid) values(3)
--insert into @uid(userid) values(5)    // I remove this line 
insert into @uid(userid) values(6)

MERGE INTO dbo.test_master AS dest
USING @uid AS sou ON
    dest.sid = @sid
    AND
    sou.userid = dest.testid
WHEN MATCHED THEN UPDATE SET
    dest.testid = sou.userid
WHEN NOT MATCHED THEN
    INSERT( sid, testid )
    VALUES( @sid, sou.userid )
--WHEN NOT MATCHED BY SOURCE
--    THEN
--        DELETE
;

我正在努力实现这个输出

5 2
5 3
5 6

我正在使用delete关键字,请参阅我的 SQL 查询,但它正在从表中删除所有记录。我尝试,但无法解决。

标签: sql-servermerge

解决方案


您需要预先过滤目标表,否则将删除所有行,即使是不同的行。sid您可以使用 CTE 或视图进行预过滤。

我注意到该WHEN MATCHED子句没有意义,因为唯一要更新的列是连接列,它显然仍然匹配。

declare @sid varchar(100) = '5';
declare @uid as userid;

insert into @uid (userid) values
  (2),
  (3),
--  (5),    -- I remove this line 
  (6);

WITH dest AS (
    SELECT *
    FROM dbo.test_master dest
    WHERE dest.sid = @sid
)
MERGE INTO dest
USING @uid AS sou ON
    sou.userid = dest.testid
-- WHEN MATCHED THEN UPDATE SET
--    dest.testid = sou.userid   -- doesn't make sense
WHEN NOT MATCHED THEN
    INSERT( sid, testid )
    VALUES( @sid, sou.userid )
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE
;

db<>小提琴


推荐阅读