web-dev-qa-db-fra.com

Transaction de procédure stockée

Je n'ai jamais utilisé de transaction, de commit et de restauration avant et je dois maintenant utiliser un. J'ai vérifié en ligne, etc. pour des exemples pour vous assurer que je l'utilise correctement, mais je ne sais toujours pas si j'ai codé ce correct. J'espère que quelqu'un peut revoir et me conseiller si cela semble correct.

Fondamentalement, j'ai 2 bases de données pour une application. L'une est une archive - une signification de données qui ne sera plus manipulée par les utilisateurs seront déplacées vers cette DB. Mais dans le cas où ils en ont déjà besoin, je déplacerai les données nécessaires à la base de données principale à utiliser. Mon procédé stocké est ci-dessous:

CREATE PROCEDURE [dbo].[spReopenClosed] 
(
    @Return_Message VARCHAR(1024) = ''  OUT,        
    @IID        uniqueidentifier,
    @OpenDate   smalldatetime,
    @ReopenedBy uniqueidentifier
)
AS
BEGIN
    SET NOCOUNT ON;

/******************************
*  Variable Declarations
*******************************/
    DECLARE     @ErrorCode  int  



/******************************
*  Initialize Variables
*******************************/

    SELECT @ErrorCode = @@ERROR

    IF @ErrorCode = 0

    BEGIN TRANSACTION
        /****************************************************************************
        * Step 1
        * Copy the Closed from the Archive
        ****************************************************************************/
        INSERT INTO OPS.dbo.SM_T_In
        SELECT          
        FROM OPS_ARCHIVE.Archive.SM_T_In    W
        WHERE W.GUID = @IID
            AND W.OpenDate = @OpenDate


        IF @ErrorCode <> 0
            BEGIN
                -- Rollback the Transaction
                ROLLBACK

                RAISERROR ('Error in Copying from the archive', 16, 1)
                RETURN
            END


        /****************************************************************************
        * Step 2
        * copy the notes
        ****************************************************************************/
        INSERT INTO OPS.dbo.SM_T_Notes
        SELECT 
        FROM OPS_ARCHIVE.Archive.SM_T_Notes W
        WHERE W.GUID = @IID

        IF @ErrorCode <> 0
            BEGIN
                -- Rollback the Transaction
                ROLLBACK

                RAISERROR ('Error in copying the notes', 16, 1)
                RETURN
            END

        /****************************************************************************
        * Step 3
        * Delete the from the Archive - this will also delete the notes
        ****************************************************************************/
        DELETE
        FROM OPS_ARCHIVE.Archive.SM_T_In
        WHERE OPS_ARCHIVE.Archive.SM_T_In.GUID = @IID

        IF @ErrorCode <> 0
            BEGIN
                -- Rollback the Transaction
                ROLLBACK

                RAISERROR ('Error in deleting the items from the Archive', 16, 1)
                RETURN
            END

        COMMIT

        BEGIN
            SELECT  @ErrorCode  = @@ERROR

            IF @ErrorCode = 0
                    SELECT  @Return_Message = 'All data was moved over'
        END



/*************************************
*  Get the Error Message for @@Error
*************************************/
    IF @ErrorCode <> 0
    BEGIN
        SELECT  @Return_Message = [Description]     -- Return the SQL Server error
          FROM  master.dbo.SYSMESSAGES
         WHERE  error = @ErrorCode
    END

/*************************************
*  Return from the Stored Procedure
*************************************/
    RETURN @ErrorCode                               -- =0 if success,  <>0 if failure
END

J'ai deux inserts qui déplacent les données de 2 tables de la base de données d'archives. Si ces insertions réussissent, je supprimerai les données de l'archive DB. J'apprécierais des commentaires à ce sujet, je dois m'assurer que je le fais bien.

Merci

17
Taryn

Premièrement, les bases de données sont assez fiables. Et s'ils échouent, vous avez un gros problème que de gérer des transactions individuelles. Donc, mes commentaires seraient que vous avez trop d'erreur vérifier une transaction simple. Un insert défaillant est un événement aussi inhabituel que vous n'écririez normalement pas de code pour le gérer.

Deuxièmement, ce code ne "attrapera" pas d'erreurs:

IF @ErrorCode <> 0

Une erreur dans l'instruction SQL abandonnera la procédure stockée et revenir au client. Vous auriez à ... essayer ... Catch Pour gérer une erreur dans une procédure stockée.

Troisièmement, j'essaie d'éviter raiserr. Il peut faire des choses inattendues sur le serveur et le côté du client. Au lieu de cela, envisagez d'utiliser un paramètre output pour renvoyer des informations d'erreur au programme client.

3
Andomar