我有一种情况,我有一个包含合并声明的存储过程。该过程从表A中获取数据并使用merge语句更新表B中的某些记录。该过程工作正常但偶尔会出现表A中存在重复记录的情况。存储过程位于包含错误通知集的包中up并且程序包在作业中运行,它给出了以下错误。有什么办法可以调试吗?像存储过程中的某些地方一样,如果它出错,那么将源数据插入表中?任何意见都表示赞赏。
由于
错误:
失败并出现以下错误:“MERGE语句尝试了 多次更新或删除同一行。这发生在a 目标行匹配多个源行。 MERGE声明不能 多次更新/删除目标表的同一行。提炼 ON子句,以确保目标行最多匹配一个源行, 或使用GROUP BY子句对源行进行分组。“。可能 失败原因:查询问题,“ResultSet”属性未设置 正确,参数设置不正确,或连接未建立 正确。
答案 0 :(得分:2)
您可以在合并程序的开头添加类似的内容:
if exists (
select 1
from a
group by a.OnColumn
having count(*)>1
)
begin;
insert into merge_err (OnColumn, OtherCol, rn, cnt)
select
a.OnColumn
, a.OtherCol
, rn = row_number() over (
partition by OnColumn
order by OtherCol
)
, cnt = count(*) over (
partition by OnColumn
)
from a
raiserror( 'Duplicates in source table a', 0, 1)
return -1;
end;
测试设置:http://rextester.com/EFZ77700
create table a (OnColumn int, OtherCol varchar(16))
insert into a values
(1,'a')
, (1,'b')
, (2,'c')
create table b (OnColumn int primary key, OtherCol varchar(16))
insert into b values
(1,'a')
, (2,'c')
create table merge_err (
id int not null identity(1,1) primary key clustered
, OnColumn int
, OtherCol varchar(16)
, rn int
, cnt int
, ErrorDate datetime2(7) not null default sysutcdatetime()
);
go
虚拟程序:
create procedure dbo.Merge_A_into_B as
begin
set nocount, xact_abort on;
if exists (
select 1
from a
group by a.OnColumn
having count(*)>1
)
begin;
insert into merge_err (OnColumn, OtherCol, rn, cnt)
select
a.OnColumn
, a.OtherCol
, rn = row_number() over (
partition by OnColumn
order by OtherCol
)
, cnt = count(*) over (
partition by OnColumn
)
from a
raiserror( 'Duplicates in source table a', 0, 1)
return -1;
end;
/*
merge into b
using a
on b.OnColumn = a.OnColumn
...
--*/
end;
go
执行test proc并检查错误表:
exec dbo.Merge_A_into_B
select *
from merge_err
where cnt > 1
结果:
+----+----------+----------+----+-----+---------------------+
| id | OnColumn | OtherCol | rn | cnt | ErrorDate |
+----+----------+----------+----+-----+---------------------+
| 1 | 1 | a | 1 | 2 | 05.02.2017 17:22:39 |
| 2 | 1 | b | 2 | 2 | 05.02.2017 17:22:39 |
+----+----------+----------+----+-----+---------------------+