首页 > 解决方案 > T-SQL MERGE 语句未插入新记录 - 我的代码有什么问题?

问题描述

下面的代码成功地更新了现有记录,但没有插入细节不匹配的新记录,我不明白为什么不作为代码编译并且不会抛出任何错误消息。我确定我错过了一些明显的东西。作为参考,我使用 SQL Server 2008 和区分大小写的排序规则,但我看不出这有什么不同。我还有其他 MERGE 案例可以正常工作,只是这一个不能很好地发挥作用。

要查看更新是否有效,请将 DEBUG 变量声明中的 colourid 修改为与插入语句中的值相同。

BEGIN TRY 
    DROP TABLE #adr_test
END TRY
BEGIN CATCH
    -- nothing to drop
END CATCH

CREATE TABLE #adr_test
(
    style NVARCHAR(5)
    ,size_id INT
    ,colour_id INT
    ,cost MONEY
)

INSERT INTO #adr_test (style, size_id, colour_id, cost) 
VALUES ('ADR01', 100, 101, 99.99)

/*DEBUG*/
DECLARE @style NVARCHAR(5) = 'ADR01'
DECLARE @sizeid INT = 100
DECLARE @colourid INT = 999
DECLARE @ctncost MONEY = 1.50
/*END DEBUG*/

MERGE #adr_test AS Tgt
USING (SELECT style, size_id, colour_id, cost
       FROM #adr_test                           
       WHERE style = @style
         AND size_id = @sizeid
         AND colour_id = @colourid) AS Src ON Src.style = Tgt.style
                                           AND Src.size_id = Tgt.size_id
                                           AND Src.colour_id = Tgt.colour_id

WHEN MATCHED AND Tgt.cost <> @ctncost 
   THEN
      UPDATE SET Tgt.cost = @ctncost

WHEN NOT MATCHED BY TARGET 
   THEN 
      INSERT (style, size_id, colour_id, cost)
      VALUES (@style, @sizeid, @colourid, @ctncost);


SELECT * FROM #adr_test

标签: tsqlsql-server-2008dmlmerge-statement

解决方案


为了详细说明 RBarry Young 和 Code Different 的响应,NOT MATCHED 将 SOURCE 中的内容与目标中的内容进行比较。因为我是从具有过滤条件的同一个表中选择的,所以源结果为 NULL,因此没有任何内容不匹配。USING 中的代码应如下所示

SELECT
    style = @style
    ,colour_id = @colourid
    ,size_id = @sizeid
    ,cost = @ctncost

这样,SOURCE 将包含一个带有单个记录的结果集,该记录可能会或可能不会在 TARGET 表中找到。当它不匹配时,插入将被触发。

谢谢你们的帮助。


推荐阅读