I get this error and it points to transaction processing and Try/Catch. I'm not very strong in SQL but particularly weak in these two areas. The code I inherited has both. The actual problem is a Merge encountered duplicates and tried updating same record twice. It would be nice to get that error in email than the one I'm getting.
As I play around trying to understand this I inserted Print @@TranCount statements in various places including the Try and Catch of the Transaction and I don't get anything inside the catch so I presume it isn't even getting to catch.
So I got to looking and this dynamic query actually has another try/catch within the query that gets executed by exec(@MergeQuery).
Questions. 1) How should this try catch be set up? Is the outer try/catch redundant?
The most important issue I'm trying to understand is the Try/Catch but I don't understand why this is even wrapped in a transaction in the first place.
--Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements
--MergeQuery1
Declare @MergeQuery1 varchar(max) = '
begin try
begin
declare @ChangeSum table(change varchar(25));
declare @Inserted int = 0;
declare @Updated int = 0;
merge into R_VISN2.TelephoneBookVisn2F528075 P
using R_Stage.TelephoneBookVisn2F528075 S
on P.[Sta3n] = S.[Sta3n] and P.[TelephoneBookVisn2F528075IEN] = S.[TelephoneBookVisn2F528075IEN]
when MATCHED then
update set ... all the columns'
Declare @MergeQuery2 varchar(max) = ' when not matched by target then '
Declare @MergeQuery3 varchar(max) = ' insert ( ...the columns) '
Declare @MergeQuery4 varchar(max) = ' values ( ...the columns ) '
Declare @MergeQuery5 varchar(max) = '
output $action into @ChangeSum;
set @Inserted = (select count(*) from @ChangeSum where change = ''INSERT'');
set @Updated = (select count(*) from @ChangeSum where change = ''UPDATE'');
select @Inserted as Inserted, @Updated as Updated;
end
end try
begin catch
end catch '
--===========================
begin transaction;
begin try
declare @MergeQuery varchar(max)
set @MergeQuery = convert(varchar(max), @MergeQuery1) + convert(varchar(max), @MergeQuery2)
+ ' ' + convert(varchar(max), @MergeQuery3)
+ ' ' + convert(varchar(max), @MergeQuery4)
+ ' ' + convert(varchar(max), @MergeQuery5);
exec(@MergeQuery);
end try
begin catch
declare
@Message VARCHAR(4000)
,@Severity INT
,@State INT;
select
@Message = ERROR_MESSAGE()
,@Severity = ERROR_SEVERITY()
,@State = ERROR_STATE();
if @@TRANCOUNT > 0
rollback transaction;
raiserror(@Message, @Severity, @State);
end catch;
if @@trancount > 0
begin
commit transaction;
end
