2

CATCHブロックでエラーが発生したときに、ブロック内のすべてのステートメントをロールバックしたいTRY:

BEGIN TRY
    begin transaction

    create table t3(a int )
    insert into t3 values(1)
    insert into t3 values(1,2)  --error occur
    insert into t3 values(3)

END TRY
BEGIN CATCH
    --just take care of rollback
    IF @@TRANCOUNT <> 0
    BEGIN
        PRINT 'in catch,ROLLING BACK';
        ROLLBACK
    END
END CATCH
go

CATCHブロック内のPRINTが機能するため、最初はエラーがキャッチされます。CATCHただし、いくつかの変更を行ったり来たりした後、印刷が行われなくなったため、エラーは発生しなくなったようです。

印刷しない

したがって、新しいクエリを開いて同じことを実行します。今回もエラーがキャッチできます!!

印刷する

大きな画像でごめんなさい

4

1 に答える 1

2

管理スタジオなどのツールでこのコードを実行すると、トランザクションは SPID (クエリ ウィンドウに割り当てられます) に対して維持されます。

したがって、一貫性のない結果の問題は、すべてのコード パスでトランザクションを閉じていないため (ロールバックに達していないとしましょう)、次にスクリプトを実行したときにトランザクションがまだアクティブになっているためです。

スクリプトの先頭に追加IF @@TRANCOUNT <> 0 rollback transactionすると、一貫した出力が得られます。

try catchまた、このブロックは、ステートメントのコンパイル レベルでエラーをキャッチするためのものではないことに注意してください。

エラーを0 による除算( )に置き換えるprint 1 / 0と、キャッチは適切に機能します。

MSDN

次のタイプのエラーは、TRY…CATCH 構文と同じ実行レベルで発生した場合、CATCH ブロックによって処理されません。

構文エラーなど、バッチの実行を妨げるコンパイル エラー。

  • オブジェクト名の解決など、ステートメント レベルの再コンパイル中に発生するエラー
  • 名前解決が延期されたためにコンパイル後に発生するエラー。
于 2013-07-04T01:58:29.700 に答える