個々のエラーをキャッチしてログに記録するために、複数の TRY/CATCH ブロックを使用する大規模なストアド プロシージャがあります。また、途中でエラーが発生した場合に全体をロールバックできるように、プロシージャの内容全体をトランザクションでラップしました (面倒なクリーンアップを防ぐため)。XACT_ABORT が有効になっているのは、トランザクション全体をロールバックしないためです。
重要なコンポーネント:
私のデータベースには、この手順が実行されるたびにレコードが挿入され、操作の結果と問題の詳細が含まれるテーブルがあります。
面白いことが起こっています-実際、何が間違っているのかを最終的に理解したとき、それはかなり明白でした...ログテーブルへの挿入ステートメントもロールバックされているため、これをSSMSから実行していない場合、ロールバックによってアクティビティの痕跡がすべて削除されるため、これが実行されたことさえ確認できません。
質問:
この単一の挿入ステートメントを除いて、トランザクション全体をロールバックすることは可能でしょうか? ストアド プロシージャの実行中にコンパイルしたエラー メッセージを保持したいと思います。
本当にありがとう!
〜エリ
更新 6/28
これは私が見ているもののコードサンプルです。これと @Alex および @gameiswar によって提示されたサンプルとの主な違いは、私の場合、try/catch ブロックがすべて単一のトランザクション内にネストされていることです。これの目的は、(複数のテーブルに対して) 複数のキャッチを取得することですが、最後の更新が失敗した場合でも、混乱全体がロールバックされるようにします。
SET XACT_ABORT ON;
BEGIN TRANSACTION
DECLARE @message AS VARCHAR(MAX) = '';
-- TABLE 1
BEGIN TRY
UPDATE TABLE xx
SET yy = zz
END TRY
BEGIN CATCH
SET @message = 'TABLE 1 '+ ERROR_MESSAGE();
INSERT INTO LOGTABLE
SELECT
GETDATE(),
@message
RETURN;
END CATCH
-- TABLE 2
BEGIN TRY
UPDATE TABLE sss
SET tt = xyz
END TRY
BEGIN CATCH
SET @message = 'TABLE 2 '+ ERROR_MESSAGE();
INSERT INTO LOGTABLE
SELECT
GETDATE(),
@message
RETURN;
END CATCH
COMMIT TRANSACTION