2011-07-27 11 views
-1

DBスキームとデータに大きな変更を加える巨大なSQLスクリプトがあります。スクリプトにはGOコマンドが含まれています。長いスクリプトにはGOコマンドが含まれています。失敗した場合は元に戻す

スクリプトを実行してエラーが発生した場合に元に戻す方法はありますか?

GOコマンドがあるので、トランザクションですべてをラップすることはできません。

+4

トランザクションは複数のバッチにまたがることができます。 –

+0

@ Martins SmithL私はすべてのスクリプトをBEGIN TRY - BEGIN TRANSACTIONでラップしましたが、それは役に立ちません。 – Naor

答えて

2

トランザクション内で複数のバッチをラップすることはできますが、それは間違っていますが、複雑なアップグレードスクリプトは1つのトランザクションで実行することはできません。あなたの最善の解決策はバックアップを取ることであり、スクリプトが失敗した場合はバックアップからデータベースを復元することです。

+0

私がやっていることは何ですか - 何度も何度もバックアップして復元しますが、これには多くの時間がかかります。私はあなたの答えから分かりませんでした。私はBEGIN TRY - BEGIN TRANSACTIONですべてを包みますか? – Naor

+0

Red Gate SQL Compareを使ったことがありますか?あなたはそれでいくつかの複雑なことをすることができます。とにかくバックアップはいつも起こるはずですが、いくつかの制御コードでは、データベースはロールバックのためのダウンタイムを必要としません(ほんの少しのブロック)。 – 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

私はですべて包むことができれば私は何を求めていますが次のとおりです。XACT_STATEは、(1) がcheckingsせずにあなたをTRAN GO をCOMMIT IF = GO TRAN GO [ALL SQL SCRIPT] をBEGIN GO ON のSET XACT_ABORTをスクリプトの途中で作られた? – Naor

関連する問題