Могу ли я изменить структуру таблицы в транзакции, а затем откатить ее в случае ошибки?

15

У меня есть несколько ALTER TABLEзаявлений, которые я выполняю. Не все из них работают (они являются результатом выполнения SQL Data Compare), и я хочу сгруппировать их в некоторые транзакции и откатить операторы, если что-то пойдет не так.

Это возможно, или это только данные, которые можно откатить?

Пирс Карсенбарг
источник
Вы говорите о Redgate SQL Compare? Один из вариантов синхронизации - использовать транзакции IIRC, чтобы вы могли посмотреть на сгенерированный скрипт, чтобы увидеть некоторый код для этого.
Мартин Смит
Да, я. Я посмотрю на это.
Пирс Карсенбарг

Ответы:

10
   BEGIN TRANSACTION
      BEGIN TRY
        ALTER TABLE1...
        ALTER TABLE2...
        -- Additional data/structural changes
        COMMIT
      END TRY
      BEGIN CATCH
         ROLLBACK;
         THROW; -- Only if you want reraise an exception (to determine the reason of the exception)
      END CATCH
Пит Картер
источник
3
Будет ли SET XACT_ABORT ONи окончательный COMMIT TRANотрицать необходимость TRYблоков?
Люк Пуплет
13

Да, это возможно

Большинство операторов DDL можно откатить в SQL Server (есть несколько исключений, таких как CREATE DATABASE)

Мартин Смит
источник
6

Много переделок в одной транзакции с rollbackи commit- это не сон. Возможно.

Вот платформа для вашего скрипта (следуя указаниям MS с улучшениями):

BEGIN TRANSACTION

BEGIN TRY
    -- place your script in this TRY block

    -- your DDL instructions:
    ALTER TABLE1...
    ALTER TABLE2...
    -- data modifications:
    EXEC('
        UPDATE A
        SET    c1 = 23,
               c2 = ''ZZXX'';
    ');
    -- another DDL instruction:
    ALTER TABLE2...

    -- end of your script
END TRY
BEGIN CATCH
    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;


    -- If you want reraise an exception (to determine the reason of the exception)
    -- just uncomment block with appropriate version:

    -- SQL SERVER > 2012
    /*
    THROW;
    */

    -- SQL SERVER < 2012 (tested against 2008 R2)
    /*
    DECLARE @ErrorMessage VARCHAR(MAX);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT
        @ErrorMessage = ERROR_MESSAGE(),
        @ErrorSeverity = ERROR_SEVERITY(),
        @ErrorState = ERROR_STATE();

    RAISERROR (
        @ErrorMessage, -- Message text.
        @ErrorSeverity, -- Severity.
        @ErrorState -- State.
    );
    */
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

Будьте внимательны, THROWработает только для версии SQL SERVER> 2012. Здесь вы можете преобразовать версию из семвера в год : http://sqlserverbuilds.blogspot.ru (не в курсе .ruдомена, есть английская версия)

maxkoryukov
источник