Могу ли я откатить динамический SQL в SQL Server / TSQL
-
13-09-2019 - |
Вопрос
Могу ли я запустить динамический 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)
Вопросы о первом ответе
@@Error, скорее всего, не обнаружит ошибку Это означает, что он может не обнаружить ошибку, что означает, что транзакция может быть зафиксирована?Что противоречит цели
ПОПРОБУЙТЕ / 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
Решение
ДА.TXN принадлежат текущему сеансу / соединению, и динамический SQL использует тот же контекст.
Однако @@ERROR, скорее всего, не обнаружит ошибку:статус должен быть проверен сразу же после оскорбительного заявления.Я бы использовал TRY / CATCH, предполагая, что SQL Server 2005+
Редактировать:ПОПЫТКА / УЛОВ должны работать нормально.
Другие советы
Не верьте нам на слово, что try catch сработает, проверьте это сами.Поскольку это динамический sql, проще всего сделать первое утверждение правильным (и, конечно, для этого требуется обновление компонента, вставка или удаление, или нет необходимости в atransaction), а затем внести преднамеренную синтаксическую ошибку во второе утверждение.Затем проверьте, что обновление insert или delete в первом сообщении прошло успешно.
Я также хочу отметить, что динамический sql как правило - плохая практика.Действительно ли это должно быть динамичным?