Puis-je modifier la structure d'une table dans une transaction, puis la restaurer en cas d'erreur?

15

J'ai quelques ALTER TABLEdéclarations que je lance. Tous ne fonctionnent pas (ils sont le résultat de l'exécution de la comparaison de données SQL) et je veux les regrouper dans certaines transactions et annuler les instructions en cas de problème.

Est-ce possible ou s'agit-il uniquement de données pouvant être annulées?

Piers Karsenbarg
la source
Parlez-vous de Redgate SQL Compare? L'une des options de synchronisation consiste à utiliser les transactions IIRC afin que vous puissiez consulter le script généré pour voir un code de plaque de chaudière à cet effet.
Martin Smith
Oui. Je vais y jeter un œil.
Piers Karsenbarg

Réponses:

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
la source
3
Est-ce que SET XACT_ABORT ONet une finale COMMIT TRANannulerait le besoin des TRYblocs?
Luke Puplett
13

Oui, c'est possible.

La plupart des instructions DDL peuvent être annulées dans SQL Server (il existe quelques exceptions telles que CREATE DATABASE)

Martin Smith
la source
6

Beaucoup de modifications en une seule transaction avec rollbacket commit- ce n'est pas un rêve. C'est possible.

Voici un échafaudage pour votre script (suivant les directives MS avec améliorations):

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

Attention, THROWne fonctionne que pour la version SQL SERVER> 2012. Ici, vous pouvez convertir une version de semver en notation annuelle : http://sqlserverbuilds.blogspot.ru (ne connaissez pas le .rudomaine, il existe une version anglaise)

maxkoryukov
la source