单存储过程中多MERGE语句执行报错求助
MERGE语句重复更新/删除同一行的问题解决
错误信息
执行存储过程时错误:System.Collections.Generic.List`1[System.String] : MERGE 语句尝试多次更新或删除同一行。这是因为目标行匹配了多个源行。MERGE 语句不能多次更新/删除目标表的同一行。请优化 ON 子句确保目标行最多匹配一个源行,或者使用 GROUP BY 子句对源行分组。
问题原因
你的代码中,即便用了distinct,如果临时表@supp或@cust里存在**同一个accountNo对应多个不同name**的记录,MERGE操作时目标表Company的同一行会匹配多个源行,触发上述错误。
修复后的代码
declare @supp table ( name nvarchar(max), accountNo nvarchar(max) ) set nocount off insert into @supp(name, accountNo) select supp_name, supp_code from (select distinct supp_name, supp_code from @orders) s -- CHECK FOR THE COMPANY DATA AND COMPARE IF NO FOUND THEN ADD NEW COMPANY merge Company as C using ( select accountNo, MAX(name) as name -- 按accountNo分组,取唯一name(MAX/MIN根据业务需求选择) from @supp group by accountNo ) as [S] on (convert(nvarchar, [S].accountNo)=c.accountNo) when matched then update set Name = [S].name when not matched then insert(name, accountno, companyTypeID) values([s].name, [s].accountno, 3); --combine declare @cust table ( name nvarchar(max), accountNo nvarchar(max) ) insert into @cust(name, accountNo) select store_name, store from (select distinct store_name, store from @orders) c merge Company as Co using ( select accountNo, MAX(name) as name -- 同样按accountNo分组去重 from @cust group by accountNo ) as [C] on (convert(nvarchar, [C].accountNo)=co.accountNo) when matched then update set Name = [C].name when not matched then insert(name, accountno, companyTypeID, disableConsignor, disableOutright) values([C].name, [C].accountno, 1, 0, 0);
关键改动说明
- 将MERGE的数据源从
select distinct name, accountNo改为按accountNo分组聚合,确保每个accountNo仅对应一条源记录,从根本上避免目标行匹配多个源行的情况 - 使用
MAX(name)(或MIN(name))统一同一accountNo下的不同名称,若需要保留特定逻辑的名称(比如最新记录),可结合时间字段调整聚合规则
内容的提问来源于stack exchange,提问作者Siri
相关产品推荐
相关产品推荐

