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.
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 .
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.