【问题标题】:Issue with delete statement in merge statement合并语句中的删除语句问题
【发布时间】:2021-12-04 19:53:38
【问题描述】:

我正在使用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 查询,但它正在从表中删除所有记录。我试了,还是不行。

【问题讨论】:

  • 您需要将您的 TYPE dbo.userid 重命名为 TYPE dbo.UserIdTable 否则您只会迷惑自己(和我们......)
  • 样本数据上的列名会有所帮助

标签: sql-server merge


【解决方案1】:

您需要预先过滤目标表,否则所有行,即使是具有不同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<>fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-25
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    相关资源
    最近更新 更多