¿Puedo cambiar la estructura de la tabla en una transacción y luego revertirla si hay un error?

15

Tengo algunas ALTER TABLEdeclaraciones que estoy ejecutando. No todos funcionan (son el resultado de ejecutar SQL Data Compare) y quiero agruparlos en algunas transacciones y revertir las declaraciones si algo sale mal.

¿Es esto posible, o son solo datos que pueden revertirse?

Piers Karsenbarg
fuente
¿Estás hablando de Redgate SQL Compare? Una de las opciones de sincronización es usar transacciones IIRC para que pueda ver el script generado allí para ver un código de placa de caldera para esto.
Martin Smith
Sí lo soy. Echaré un vistazo a eso.
Piers Karsenbarg

Respuestas:

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
Pete Carter
fuente
3
¿ SET XACT_ABORT ONY una final COMMIT TRANnegaría la necesidad de los TRYbloques?
Luke Puplett el
13

Si, esto es posible.

La mayoría de las declaraciones DDL se pueden revertir en SQL Server (hay algunas excepciones como CREATE DATABASE)

Martin Smith
fuente
6

Muchas alteraciones en una transacción con rollbacky commit- no es un sueño. Es posible.

Aquí hay un andamio para su script (siguiendo las pautas de MS con mejoras):

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

Tenga cuidado, THROWsolo funciona para la versión SQL SERVER> 2012. Aquí puede convertir una versión de notación de semver a año : http://sqlserverbuilds.blogspot.ru (no conoce el .rudominio, hay una versión en inglés)

maxkoryukov
fuente