我有一个TSQL脚本,它可以进行大量的数据库结构调整,但是在发生故障时让它通过并不安全。
要说清楚:
我得到的是按以下顺序排列的东西
BEGIN TRANSACTION
ALTER Stuff
GO
CREATE New Stuff
GO
DROP Old Stuff
GO
IF @@ERROR != 0
BEGIN
PRINT 'Errors Found ... Rolling back'
ROLLBACK TRANSACTION
RETURN
END
ELSE
PRINT 'No Errors ... Committing changes'
COMMIT TRANSACTION只是为了说明我的工作..。现在不能详细说明问题..。
当我引入一个错误(测试是否回滚)时,我得到一条语句,即ROLLBACK事务找不到相应的BEGIN事务。这让我相信,当真的出错的时候,交易已经被扼杀了。我还注意到,脚本没有在错误时完全退出,因此在错误发生后尝试执行所有语句。(当新表出现时,我注意到了这一点,当时我并没有想到它们,因为它应该回滚)
发布于 2010-05-26 08:16:21
发生错误时,事务将自动回滚,当前批处理将被中止。
然而,执行将继续到下一批。所以,在执行错误后,批中的所有内容都在批中。然后,当稍后检查错误时,尝试回滚已经回滚的事务。
此外,要停止整个脚本,而不仅仅是当前批处理,您应该使用:
raiserror('Error description here', 20, -1) with log有关该问题的详细信息,请参见my answer here。
因此,您需要在每一批之后检查@error,我认为这样的方法应该有效:
BEGIN TRANSACTION
GO
ALTER Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
CREATE New Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
DROP Old Stuff
GO
if @@error != 0 raiserror('Script failed', 20, -1) with log
GO
PRINT 'No Errors ... Committing changes'
COMMIT TRANSACTION发布于 2012-06-12 21:50:36
试着用回音。这将立即退出脚本或过程,并且不会执行以下任何语句。可以将此与BEGIN、ROLLBACK和COMMIT事务语句结合使用,以撤消任何数据损坏:
BEGIN
BEGIN TRANSACTION
<first batch>
IF @@error <> 0
begin
RAISERROR ('first batch failed',16,-1)
ROLLBACK TRANSACTION
RETURN
end
<second batch>
IF @@error <> 0
begin
RAISERROR ('second batch failed',16,-1)
ROLLBACK TRANSACTION
RETURN
end
PRINT 'WIN!'
COMMIT TRANSACTION
END发布于 2011-10-25 12:33:32
我没有使用上升错误解决方案,因为它失败了,因为我没有管理权限。我用事务处理扩展了noexec on/off解决方案,如下所示:
set noexec off
begin transaction
go
<First batch, do something here>
go
if @@error != 0 set noexec on;
<Second batch, do something here>
go
if @@error != 0 set noexec on;
<... etc>
declare @finished bit;
set @finished = 1;
SET noexec off;
IF @finished = 1
BEGIN
PRINT 'Committing changes'
COMMIT TRANSACTION
END
ELSE
BEGIN
PRINT 'Errors occured. Rolling back changes'
ROLLBACK TRANSACTION
END显然,编译器“理解”IF中的@finished变量,即使出现错误并禁用了执行。但是,只有在未禁用执行时,该值才被设置为1。因此,我可以很好地提交或回滚事务。
https://stackoverflow.com/questions/2911103
复制相似问题