sql-server - SQL合并错误: The MERGE statement attempted to UPDATE or DELETE

标签 sql-server tsql merge

我有一个源表

select 54371 Id, 'foo' [CreateBy], '2016-10-24 09:29:18.548'[CreateDate], 'foo'[UpdateBy],  '2016-10-24 09:29:18.548'[UpdateDate], 'E'[MT], 185761[MID], 3[BGID]
union
select 54372, 'foo', '2016-10-24 09:30:18.548', 'foo',  '2016-10-24 09:30:18.548',  'E', 185761, 2

和目标表

select 54379 Id, 'foo' [CreateBy], '2016-10-24 09:29:18.548'[CreateDate], 'foo'[UpdateBy],  '2016-10-24 10:29:18.548'[UpdateDate], 'E'[MT], 185761[MID], 3[BGID]

我想要的是基于MT、MID进行匹配

  1. 如果不存在则插入
  2. 如果 BGID 匹配则更新
  3. 如果 BGID 不匹配则删除

当我使用 SQL 合并语句时出现错误

The MERGE statement attempted to UPDATE or DELETE the same row more than once. This happens when a target row matches more than one source row. A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times. Refine the ON clause to ensure a target row matches at most one source row, or use the GROUP BY clause to group the source rows.`

我的合并是这样的

MERGE   
  FooBar AS target
USING
(
SELECT
E.[Id],
E.[CreateBy],
E.[CreateDate],
E.[UpdateBy],
E.[UpdateDate],
E.[MT],
E.[MID],
E.[BGID]
FROM @FooBar E
) AS source
ON
source.MID = target.MID
AND source.MT = target.MT
WHEN MATCHED and target.[BGID] = source.[BGID] THEN
UPDATE SET
target.[UpdateBy] = Source.[UpdateBy]
,target.[UpdateDate] = Source.[UpdateDate]
When Matched and source.BGID <> target.BGID THEN
DELETE
WHEN NOT MATCHED THEN
INSERT([CreateBy]
,[CreateDate]
,[UpdateBy]
,[UpdateDate]
,[MT]
,[MID]
,[BGID])
VALUES
(
Source.[CreateBy]
,Source.[CreateDate]
,Source.[UpdateBy]
,Source.[UpdateDate]
,Source.[MT]
,Source.[MID]
,Source.[BGID]
);

我错过了什么?

最佳答案

您正在加入 ON source.MappingId = target.MappingId 上的表。

在您的数据示例中,有超过 1 行具有相同的 MappingId = 185761。 所以你得到了:

A MERGE statement cannot UPDATE/DELETE the same row of the target table multiple times.

您需要指定一些唯一的列组合来连接目标表。

关于sql-server - SQL合并错误: The MERGE statement attempted to UPDATE or DELETE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40217140/

相关文章:

sql - 我可以将一行一列的子查询视为标量吗?

sql - 使用 SQL 从表中选择正确的数据

SQL子选择如果存在

sql-server - SQL如何检查带有两个前缀的单元格中的前缀

c# - 如何将数据表从 C# 传递到 SQL Server 存储过程

mysql - sql server 中 where 子句中的 case 语句与 else 始终为真

mysql - 与 MySQL 合并间隔

Java 按元素合并两个列表

java - 如何通过比较 Java 中给定对象中的字段值来合并两个对象列表

c# - 捕获 block 未在存储过程中执行