[英]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.