web-dev-qa-db-fra.com

Comment obtenir une erreur SQL dans une procédure stockée

J'utilise SQL Server 2005. J'ai créé une procédure stockée qui fonctionne la plupart du temps, mais j'ai trouvé une instance où il ne fait pas ce que je veux.

Actuellement, le code fait quelque chose comme ça

if @@error <> 0
  begin
   select @message_error = "There was a database error adding product "+ @product + " to product line
  end

@message_error est une variable de sortie.

Donc je peux select @@error et obtenir un numéro, mais tout ce que je veux vraiment, c'est l'erreur SQL.

Quelque chose comme Hé, je ne pouvais pas faire ça car il y a une contrainte fk sur cette colonne ou autre chose. J'ai trouvé cet article sur msdn http://msdn.Microsoft.com/en-us/library/ms178592 (v = sql.90) .aspx

Mais cela ne fait que lancer des exceptions personnalisées avec RAISERROR, je ne veux pas créer mon propre message d'erreur ou exception, je veux juste savoir pourquoi les choses ne fonctionnent pas. Je peux exécuter la procédure stockée via Management Studio et voir l'erreur SQL exacte, mais il est fastidieux d'essayer de faire correspondre les données du site et de les insérer manuellement de cette façon.

Comment obtenir le texte d'erreur SQL dans une variable de sortie?

11
Steve's a D

Voici une partie d'un modèle de procédure stockée que j'utilise:

/*  CREATE PROCEDURE...  */

DECLARE
  @ErrorMessage   varchar(2000)
 ,@ErrorSeverity  tinyint
 ,@ErrorState     tinyint

/*  Additional code  */

BEGIN TRY

/*  Your code here  */

END TRY

BEGIN CATCH
    SET @ErrorMessage  = ERROR_MESSAGE()
    SET @ErrorSeverity = ERROR_SEVERITY()
    SET @ErrorState    = ERROR_STATE()
    RAISERROR(@ErrorMessage, @ErrorSeverity, @ErrorState)

    BREAK
END CATCH

/*  Further cleanup code  */

Les blocs Try/Catch peuvent être délicats mais sont beaucoup plus approfondis que l'erreur @@. Plus important encore, vous pouvez utiliser les diverses fonctions error_xxx () qu'elles contiennent. Ici, je stocke le message d'erreur approprié dans la variable @ErrorMessage, avec suffisamment d'autres données pour relancer l'erreur. À partir d'ici, un certain nombre d'options sont disponibles; vous pouvez faire de @ErrorMessage une variable de sortie, tester et gérer des erreurs spécifiques, ou créer vos propres messages d'erreur (ou ajuster les messages existants pour être plus clairs - vous pourriez être irrité de découvrir à quelle fréquence vous voudrez le faire). D'autres options vous présenteront eux-mêmes.

Quelque chose à surveiller: dans certaines situations, SQL enverra deux messages d'erreur dos à dos ... et error_message() n'attrapera que le dernier, qui dit généralement quelque chose comme "la tentative de création d'un objet a échoué", avec l'erreur réelle indiquée dans le premier message d'erreur. C'est là qu'intervient la création de votre propre message d'erreur.

19
Philip Kelley

Vous pouvez utiliser un Try/Catch général, puis construire plus de détails sur l'erreur dans la section CATCH, par exemple.

DECLARE @DetailedErrorDesc VARCHAR(MAX)
BEGIN TRY

--tsql code goes here

END TRY
BEGIN CATCH

SELECT @DetailedErrorDesc =         
  CAST(ERROR_NUMBER() AS VARCHAR) + ' : '+
  CAST(ERROR_SEVERITY() AS VARCHAR) + ' : ' +
  CAST(ERROR_STATE() AS VARCHAR) + ' : ' +
  ERROR_PROCEDURE() + ' : ' +
  ERROR_MESSAGE() + ' : ' +
  CAST(ERROR_LINE() AS VARCHAR);

--Now you can decide what to do with the detailed error message....return it or log it etc

END CATCH
12
Myles J

utilisez try ... catch et dans le bloc catch vous pouvez utiliser les fonctions ERROR_MESSAGE (), ERROR_LINE (), ERROR_PROCEDURE (), ERROR_STATE (), ERROR_SEVERITY (), ERROR_NUMBER ()

3
Eduard Bader