繁体   English   中英

MERGE 语句更新或插入行到表中

[英]MERGE statement to update or insert rows into a table

我的任务是在 table2 中插入或更新行。 表 1 包含所有员工的 ID。 该 id 与 table2 中的 ID 匹配。 table2 中的一些员工已经有了我需要的行,但有些没有。 表 2 不包含没有这些行的员工的 ID。

我的任务是更新现有 ID 的行并插入没有这些行的行。

我试过以下声明:

MERGE INTO dbo.table2 AS TGT
USING (SELECT table1ID FROM dbo.table1) AS SRC
      ON SRC.table1ID = TGT.table2ID

WHEN MATCHED 
     AND table2Code = 'ValueToInsertOrUpdateCode'
    THEN
       UPDATE 
       SET table2Value= 'ValueToInsertOrUpdateValue'

WHEN NOT MATCHED BY TARGET 
    THEN
        INSERT (table2Code, table2ID, table2Value)
        VALUES ('ValueToInsertOrUpdateCode', src.table1ID, 'ValueToInsertOrUpdateValue'); 

这目前只更新存在的行,但不会插入没有现有行的 ID 的行。

老实说,我会建议避免使用MERGE运算符,而是在此处执行 Upsert。 对于您的场景,您最有可能需要以下内容:

SET XACT_ABORT ON;
BEGIN TRANSACTION;

UPDATE T2 WITH (UPDLOCK, SERIALIZABLE) 
SET table2Value = 'ValueToInsertOrUpdateValue'
FROM dbo.Table2 T2
     JOIN dbo.Table1 T1 ON T1.table1ID = T2.table2ID;
-- You could honestly use an EXISTS here, considering that you're updating the table
-- with a literal, rather than a value from the table Table1.

INSERT INTO dbo.Table2 (table2Code , table2ID, table2Value)
SELECT 'ValueToInsertOrUpdateCode',
       T1.table1ID,
       'ValueToInsertOrUpdateValue'
FROM dbo.Table1 T1
WHERE NOT EXISTS (SELECT 1
                  FROM dbo.Table2 T2
                  WHERE T2.table2ID = T1.table1ID);

COMMIT;

数据库<>小提琴

根据您的评论,听起来您想要这样,以便执行WHEN NOT MATCHED BY TARGET

MERGE INTO dbo.table2 AS TGT
USING (SELECT table1ID FROM dbo.table1) AS SRC
      ON (SRC.table1ID = TGT.table2ID AND table2Code = 'ValueToInsertOrUpdateCode') -- This is the difference

WHEN MATCHED 
     AND table2Code = 'ValueToInsertOrUpdateCode'
    THEN
       UPDATE 
       SET table2Value= 'ValueToInsertOrUpdateValue'

WHEN NOT MATCHED BY TARGET 
    THEN
        INSERT (table2Code, table2ID, table2Value)
        VALUES ('ValueToInsertOrUpdateCode', src.table1ID, 'ValueToInsertOrUpdateValue'); 

SRC.table1ID = TGT.table2ID (即它们匹配)时, WHEN NOT MATCHED BY TARGET将不会执行。

ON子句更新为ON (SRC.table1ID = TGT.table2ID AND table2Code = 'ValueToInsertOrUpdateCode')将为您提供您期望的插入。

但是你可能不应该这样做:
ON <merge_search_condition> 注意事项

仅指定目标表中用于匹配目的的列很重要。 也就是说,指定目标表中与源表的相应列进行比较的列。 不要试图通过在 ON 子句中过滤掉目标表中的行来提高查询性能; 例如,指定 AND NOT target_table.column_x = value。 这样做可能会返回意外和不正确的结果。

出于这个原因以及其他人的建议,执行单独的更新和插入语句会更安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM