Чи можу я змінити структуру таблиці в транзакції, а потім повернути її назад, якщо є помилка?


15

У мене є деякі ALTER TABLEзаяви, що я балотуюся. Не всі вони працюють (вони є результатом запуску даних порівняння SQL), і я хочу згрупувати їх у деяких транзакціях і відмовити заяви, якщо щось піде не так.

Це можливо чи це лише дані, які можна повернути назад?


Ви говорите про порівняння Redgate SQL? Один з варіантів синхронізації - це використовувати транзакції 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. Тут ви можете перетворити версію з semver в рік нотацію : http://sqlserverbuilds.blogspot.ru (не відомо про .ruдомені, є англійська версія)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.