2011-07-27 31 views
-1

我有一个巨大的sql脚本,在我的db方案和我的数据中做了很多更改。该脚本包含GO命令。长脚本包括GO命令 - 如果失败则撤消

是否有任何方法来执行脚本并在发生任何错误时将其撤消?

因为有GO命令,所以我不能在事务中包装所有东西。

+4

事务可以跨越多个批次。 –

+0

@Martin SmithL我用BEGIN TRY - BEGIN TRANSACTION包装了所有的脚本,但这没有帮助。 – Naor

回答

2

您可以在一个事务中包装多个批次,但您认为这是错误的,但事实是复杂的升级脚本不太可能在单个事务中执行。如果脚本无法从备份中恢复数据库,最好的解决方案是进行备份。

+0

这就是我正在做的 - 备份和恢复一遍又一遍,但这需要很多时间..我不明白从你的答案,我可以包装一切在BEGIN TRY - BEGIN TRANSACTION? – Naor

+0

你有没有使用红门SQL比较?你可以用它做一些复杂的事情。无论如何总是应该发生备份,但是对于一些控制代码,数据库不需要停机(仅仅是一些阻塞)。 – gbn

+0

您可以将所有内容都包含在BEGIN TRANSACTION/COMMIT中,但不能在BEGIN TRY中尝试,TRY/CATCH块仍然需要在一个批次中进行。 –

1

最好的方法是使用SET XACT_ABORT ON。这是批量中止并自动回滚。所以......

SET XACT_ABORT ON 
GO 
BEGIN TRAN 
GO 
--DO stuff 
GO 
IF XACT_STATE() = 1 
    --do more stuff 
GO 
IF XACT_STATE() = 1 
    --do more stuff 
GO 
.... 
GO 
IF XACT_STATE() = 1 
    COMMIT TRAN 
GO 

您可以使用TRY/CATCH每批结合本和/或使用临时表来控制流量(根据红门SQL比较脚本)

+0

IF XACT_STATE()= 1是否必需?这个是来做什么的? – Naor

+0

@Naor:它测试以查看交易是否仍然开放。 SET XACT_ABORT ON将回滚XACT_STATE()= 0。您可以使用@@ TRANCOUNT,但XACT_STATE()对此更有用。 – gbn

+0

我要问,如果我可以换的一切是: SET XACT_ABORT ON GO BEGIN TRAN GO [ALL SQL脚本] GO IF XACT_STATE()= 1 COMMIT TRAN GO 没有checkings你在剧本中间做出来的? – Naor