与递归合并插入/更新

时间:2014-09-30 20:29:37

标签: sql sql-server

假设我有2张桌子,

DECLARE @BaseProducts TABLE (Id int)
DECLARE @ConnectData TABLE (Id int, ACTION varchar(10))

我在@ConnectData中有一些数据,

INSERT INTO @ConnectData (Id, ACTION)
VALUES (1, 'Insert')
INSERT INTO @ConnectData (Id, ACTION)
VALUES (1, 'Insert')
INSERT INTO @ConnectData (Id, ACTION)
VALUES (1, 'Insert')

现在我想从@ConnectData更新@BaseProduct,所以我尝试了

MERGE @BaseProducts AS D
USING (SELECT Id, ACTION FROM @ConnectData) S 
    ON D.Id = S.Id
WHEN NOT MATCHED THEN
    INSERT(Id)
    VALUES(S.Id)
WHEN MATCHED THEN
UPDATE
        SET Id = S.Id;

但这是插入3行。我希望第一个应该插入,其他2应该更新。

2 个答案:

答案 0 :(得分:0)

您正在以错误的方式处理此问题,Merge语句在MATCHED之前应该有NOT MATCHED个案例。

你在这里尝试做什么MERGE Statement不是正确的工具。你应该做一个像这样的独特插入..

也不要看到更新带ID的ID,因为两个值都相同(因此你加入了它们)。

INSERT INTO @BaseProducts (Id)
SELECT t.Id
FROM @ConnectData t
WHERE NOT EXISTS (SELECT 1 
                  FROM @BaseProducts
                  WHERE ID = t.Id)
GROUP BY t.Id

答案 1 :(得分:0)

MERGE不会对MERGE本身新插入的行采取行动。

为了达到你的需要,

您需要将基于NOT MATCHED的不同值插入空表

MERGE @BaseProducts AS D
USING (SELECT distinct Id, ACTION FROM @ConnectData) S 
    ON D.Id = S.Id
WHEN NOT MATCHED THEN
    INSERT(Id)
    VALUES(S.Id);

你可以根据MATCHED条件

再做一次MERGE更新
MERGE @BaseProducts AS D
USING (SELECT distinct Id, ACTION FROM @ConnectData) S 
    ON D.Id = S.Id
WHEN MATCHED THEN
UPDATE
        SET Id = S.Id;