web-dev-qa-db-fra.com

Comment annuler une transaction SQL Server et utilisez la sortie Param?

J'essaie de définir une sortie de sortie dans une procédure stockée, mais je pense que lorsque je retourne la transaction, je pense que je roulais également la mission à @out. Est-ce exact?

Si oui, comment puis-je retourner un message et retourner une transaction? Je récupère le @out param de c #.

create PROCEDURE [dbo].[sp]
@out varchar(2000) output
AS
BEGIN
    SET NOCOUNT ON
    BEGIN TRANSACTION
    BEGIN TRY
        SET @OUT = "success";
        COMMIT TRANSACTION
    END TRY

    BEGIN CATCH
        set @out = 'not success';
        ROLLBACK TRANSACTION
    END CATCH
END

Je faisais à l'origine un

SELECT 
    ERROR_NUMBER() AS ErrorNumber,
    ERROR_SEVERITY() AS ErrorSeverity,
    ERROR_STATE() AS ErrorState,
    ERROR_PROCEDURE() AS ErrorProcedure,
    ERROR_LINE() AS ErrorLine,
    ERROR_MESSAGE() AS ErrorMessage;

... Mais cela n'a pas aidé, bien que je préférerais cette méthode.

1
Zach Smith

Une manière plus robuste d'écrire cette procédure stockée serait la suivante:

CREATE PROCEDURE dbo.sp
AS
BEGIN
    SET XACT_ABORT, NOCOUNT ON;

    BEGIN TRY
        BEGIN TRANSACTION;

        SELECT 1/0; -- An error!

        /* Other good code omitted*/

        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;

        DECLARE @Message nvarchar(2048) = ERROR_MESSAGE();
        DECLARE @Severity integer = ERROR_SEVERITY();
        DECLARE @State integer = ERROR_STATE();

        RAISERROR(@Message, @Severity, @State);
        RETURN -1;
    END CATCH;
END;

Notez l'utilisation de XACT_ABORT et rien de conséquence avant le BEGIN TRY. Aussi RAISERROR est souvent préféré sur THROW pour des raisons couvertes de la référence ci-dessous, mais de manière importante:

Dans la différence pour RaisError, le lancer abrite toujours le lot.

Abandonner les résultats du lot dans tous les paramètres de sortie ne pas être attribué .

La manutention des erreurs dans SQL Server est originale de l'extrême, de sorte que je vous encourageons à examiner le travail séminal sur le sujet par Erland Sommarskog: Traitement des erreurs et de la transaction dans SQL Server .

7
Paul White 9

Puisque vous utilisez SQL Server 2016, je vous recommanderais d'utiliser THROW

Cela prendra l'erreur qui a provoqué la construction de la construction TRY pour détourner à la construction CATCH et jetez la même erreur à nouveau.

Si vous le souhaitez ici, vous pouvez également enregistrer l'erreur à une table, faire des exercices de nettoyage que le ROLLBACK ne le fera pas, etc.

Pour être clair, à l'application d'appel, cela constituera une exception et non un ensemble de résultats.

Remarque: la déclaration avant le THROW doit être terminée avec un point-virgule, sinon elle peut être interprétée comme par exemple. ROLLBACK TRANSACTION THROW avec THROW comme nom de transaction ou de sauvegarde.

3
George.Palacios