Можно ли откатить динамический SQL в SQL Server / TSQL - PullRequest
4 голосов
/ 07 декабря 2009

Можно ли запустить динамический sql в транзакции и выполнить откат с помощью EXEC:

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

Поместите это в транзакцию и используйте ошибку @@ после оператора exec для выполнения отката.

например. Код

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) операторов


Вопросы о первом ответе

@@ Ошибка, скорее всего, не обнаружит ошибку Что означает, что он может не уловить ошибку, что означает, что транзакция может быть зафиксирована? Который побеждает цель

TRY / CATCH в SQL Server 2005+ Да, я использую 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

Ответы [ 2 ]

7 голосов
/ 07 декабря 2009

Да. TXN принадлежат текущему сеансу / соединению, а динамический SQL использует тот же контекст.

Тем не менее, @@ ERROR, скорее всего, не обнаружит ошибку: статус должен быть проверен сразу после сообщения об ошибке. Я бы использовал TRY / CATCH, предполагая, что SQL Server 2005 +

Редактировать: TRY / CATCH должен работать нормально.

0 голосов
/ 07 декабря 2009

Не верьте нам на слово, что попытка поймать сработает, проверьте сами. Так как это динамический sql, проще всего сделать правильный первый оператор (и, конечно, он требует обновления, вставки или удаления компонента, или нет необходимости в транзакции), а затем сделать преднамеренную синтаксическую ошибку во второй статистике. Затем проверьте, что обновление вставлено или удалено в первом отчете.

Я также хочу отметить, что динамический sql, как правило, плохая практика. Это действительно должно быть динамическим?

...