Posso alterar a estrutura da tabela em uma transação e revertê-la se houver um erro?

15

Eu tenho algumas ALTER TABLEdeclarações que estou executando. Nem todos eles funcionam (eles são o resultado da execução do SQL Data Compare) e quero agrupá-los em algumas transações e reverter as instruções se algo der errado.

Isso é possível ou são apenas dados que podem ser revertidos?

Piers Karsenbarg
fonte
Você está falando sobre o Redgate SQL Compare? Uma das opções de sincronização é usar as transações IIRC para que você possa olhar o script gerado lá para ver algum código da placa da caldeira para isso.
Martin Smith
Sim, eu sou. Vou dar uma olhada nisso.
Piers Karsenbarg

Respostas:

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
fonte
3
Would SET XACT_ABORT ONe uma final COMMIT TRANnegar a necessidade dos TRYblocos?
Luke Puplett
13

Sim, isso é possível.

A maioria das instruções DDL pode ser revertida no SQL Server (existem algumas exceções, como CREATE DATABASE)

Martin Smith
fonte
6

Muitas alterações em uma transação com rollbacke commit- não é um sonho. É possível.

Aqui está um suporte para o seu script (seguindo as diretrizes da Microsoft com melhorias):

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

Cuidado, THROWfunciona apenas para a versão SQL SERVER> 2012. Aqui você pode converter uma versão de semver para notação de ano : http://sqlserverbuilds.blogspot.ru (não tem conhecimento do .rudomínio, existe uma versão em inglês)

maxkoryukov
fonte