4

トランザクションで動的 SQL を実行し、EXEC を使用してロールバックできますか?

exec('SELECT * FROM TableA; SELECT * FROM TableB;');

これをトランザクションに入れ、exec ステートメントの後に @@error を使用してロールバックを行います。

例えば。コード

BEGIN TRANSACTION

   exec('SELECT * FROM TableA; SELECT * FROM TableB;');

   IF @@ERROR != 0
     BEGIN
       ROLLBACK TRANSACTION
       RETURN
     END
   ELSE
     COMMIT TRANSACTION

n 個の動的 SQL ステートメントがあり、n/2 でエラーが発生した場合、最初の 1 個から ((n/2) - 1) 個のステートメントがロールバックされます。


最初の回答に関する質問

@@Error でエラーが検出されない可能性が最も高い エラーが検出されない可能性があるということは、トランザクションがコミットされる可能性があることを意味します。目的に反するもの

SQL Server 2005+ での TRY/CATCH はい SQL Server 2005 を使用していますが、以前に Try Catch を使用したことがありません。

BEGIN TRANSACTION 
   BEGIN TRY 
      exec('SELECT * FROM TableA; SELECT * FROM TableB;'); 
      COMMIT TRANSACTION 
   END TRY 
   BEGIN CATCH 
      ROLLBACK TRANSACTION 
   END CATCH 

または、ネットでさらにいくつかの例を見ました

BEGIN TRY --Start the Try Block..
 BEGIN TRANSACTION -- Start the transaction..
  exec('SELECT * FROM TableA; SELECT * FROM TableB;');
 COMMIT TRAN -- Transaction Success!
END TRY
BEGIN CATCH
  IF @@TRANCOUNT > 0
      ROLLBACK TRAN --RollBack in case of Error
  RAISERROR(ERROR_MESSAGE(), ERROR_SEVERITY(), 1)
END CATCH
4

2 に答える 2

7

はい。TXN は現在のセッション/接続に属し、動的 ​​SQL は同じコンテキストを使用します。

ただし、@@ERROR はおそらくエラーを検出しません。問題のあるステートメントの直後にステータスを確認する必要があります。SQL Server 2005+を想定して、TRY/CATCHを使用します

編集: TRY/CATCH は正常に動作するはずです。

于 2009-12-07T07:11:41.310 に答える
0

try catch が機能するという私たちの言葉を鵜呑みにしないで、自分でテストしてください。これは動的SQLであるため、最も簡単な方法は、最初のステートメントを正しくすることです(もちろん、Beanの更新、挿入、または削除が必要であるか、トランザクションの必要はありません)。次に、2番目のステートメントで意図的な構文エラーを作成します。次に、最初のステートメントの更新の挿入または削除が完了したことをテストします。

また、ルールとしての動的SQLは不適切な方法であることも指摘したいと思います。これは本当に動的である必要がありますか?

于 2009-12-07T14:34:11.827 に答える