Sql server 错误时回滚事务
我有一个大的生成脚本。它有多个批处理GO语句。第一行是BEGIN TRAN 如果在执行过程中发生任何错误,或者是使用RAISERROR引发的错误,或者是由SQL Server引发的错误,我希望回滚事务。我希望脚本继续执行到最后,然后回滚,而不是在出现任何错误时立即中止执行 在脚本末尾检查@错误0似乎不够,因为如果脚本中的最后一条语句成功,@@error将为0,即使以前的语句失败 我不能在一开始就声明@rollback位,因为脚本被分割成多个批,因此变量超出范围 我理解RAISERROR并不意味着我的事务将被回滚 关于以兼容SQL 2000的方式实现此功能的最佳方法,您有什么建议吗?您可以始终使用来传递“带外”信息,稍后使用阅读。如果发生错误,请将上下文信息设置为在提交之前检查的值Sql server 错误时回滚事务,sql-server,sql-server-2005,transactions,Sql Server,Sql Server 2005,Transactions,我有一个大的生成脚本。它有多个批处理GO语句。第一行是BEGIN TRAN 如果在执行过程中发生任何错误,或者是使用RAISERROR引发的错误,或者是由SQL Server引发的错误,我希望回滚事务。我希望脚本继续执行到最后,然后回滚,而不是在出现任何错误时立即中止执行 在脚本末尾检查@错误0似乎不够,因为如果脚本中的最后一条语句成功,@@error将为0,即使以前的语句失败 我不能在一开始就声明@rollback位,因为脚本被分割成多个批,因此变量超出范围 我理解RAISERROR并不意味着
这回答了你关于如何做这件事的问题,但我真的不得不表达我对为什么要首先做这件事的怀疑。例如,许多错误无论如何都会中止事务,因此您可能会盲目地认为继续是安全的,然后回滚,结果发现在提交异常后没有什么可回滚的内容以及所有错误脚本。第二,对于异常比不中止事务,仍然很有疑问的是做任何工作只是为了回滚它。你的请求太离经叛道了,我想知道你是否真的理解你所做的一切的含义。一种常见的技术是创建一个临时表,并在每个批处理结束时使用样板代码
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
您没有收到错误:提交事务请求没有相应的开始事务。?否,我不知道……即使我提前提出错误,事务也会在最后提交。我希望整个脚本都能运行,这样用户就可以得到脚本中所有需要更正的错误的列表……否则,他们需要一次更正一个错误。关于这件事,我当然愿意接受其他建议。谢谢。不过,该脚本也有几个EXEC“…”语句。语法分析只适用于此吗?我认为SET CONTEXT_INFO是在SQL中引入的2005@Clint:SET CONTEXT_INFO在SQL 2000中:@Jeff:否,仅解析不会处理EXEC或sp_executesql调用。