Reputation: 36573
I have a large generated script. It has multiple batches (GO
statements). The first line is BEGIN TRAN
If any errors occur during execution, either raised myself using RAISERROR
, or raised by SQL Server, I want to rollback the transaction. I want the script to continue executing until the very end, then rollback, not abort execution as soon as any error occurs.
Checking @@error <> 0
at the end of the script doesn't seem to be sufficient, because if the last statement in the script succeeds, @@error will be 0, even though previous statements failed.
I can't declare a @rollback BIT
at the very beginning because the script is segmented into multiple batches, and so the variable is out of scope.
I understand that RAISERROR
doesn't mean my transaction will be rolled back.
Any suggestions on the best way to implement this in a SQL 2000 compatible manner?
Upvotes: 2
Views: 2426
Reputation: 850
A common technique is to create a temporary table and use boilerplate code at the end of each batch
begin tran
go
create table #errors (errorid int not null)
go
select 1/ 0
declare @error int
set @error = @@error
if @error <> 0 insert into #errors values (@error)
go
select 1/ 1
declare @error int
set @error = @@error
if @error <> 0 insert into #errors values (@error)
go
if exists (select * from #errors)
begin
print 'rolling back transaction'
select * from #errors
rollback tran
end
else
begin
print 'commit transaction'
commit tran
end
go
if OBJECT_ID('tempdb..#errors') is not null
drop table #errors
go
Upvotes: 1
Reputation: 294237
You can always use SET CONTEXT_INFO
to pass 'out-of-band' information, and read it later using CONTEXT_INFO()
. If an error occurs, set the context info to a value which you check just before commit.
This answers your question of how to do it, but I really have to express my doubts about why do it in the first place. For one many errors will abort the transaction anyway so you may blindly proceed believing that is safe to continue and rollback only to discover that there is nothing to rollback and all your erroneous script after the exception has committed. Second, for the exceptions than do not abort the transaction, is still very questionable to do any work only to roll it back. Your request is so out of the beaten path than I must wonder if you really understand all the implications of what you're doing.
Upvotes: 2