web-dev-qa-db-fra.com

Comment puis-je obtenir le numéro de ligne de procédure stockée réel à partir d'un message d'erreur?

Lorsque j'utilise SQL Server et qu'il y a une erreur, le message d'erreur indique un numéro de ligne sans corrélation avec les numéros de ligne de la procédure stockée. Je suppose que la différence est due aux espaces et aux commentaires, mais est-ce vraiment?

Comment puis-je relier ces deux séries de numéros de ligne? Si quelqu'un pouvait me donner au moins un pointeur dans la bonne direction, je l'apprécierais vraiment.

J'utilise SQL Server 2005.

TIA!

99
chama

IIRC, il commence à compter les lignes à partir du début du lot qui a créé ce proc. Cela signifie soit le début du script, soit la dernière instruction "GO" avant l'instruction create/alter proc.

Une méthode plus simple consiste à extraire le texte utilisé par SQL Server lors de la création de l'objet. Basculez votre sortie en mode texte (CTRL-T avec les mappages de touches par défaut) et exécutez

sp_helptext proc_name

Copier coller les résultats dans une fenêtre de script pour obtenir la coloration syntaxique, etc., et utiliser la fonction de ligne goto (CTRL-G, je pense) pour afficher la ligne d'erreur indiquée.

103
Rick

Par habitude, je place LINENO 0 directement après BEGIN dans mes procédures stockées. Cela réinitialise le numéro de ligne - à zéro, dans ce cas. Ensuite, ajoutez simplement le numéro de ligne indiqué par le message d'erreur au numéro de ligne dans SSMS où vous avez écrit LINENO 0 et bingo - vous avez le numéro de ligne de l'erreur tel qu'il est représenté dans la fenêtre de requête.

20
Vorlic

En fait, ce Error_number() fonctionne très bien. 

Cette fonction commence à compter à partir de la dernière instruction GO (séparateur de lots). Par conséquent, si vous n'avez pas utilisé d'espaces Go et qu'elle affiche toujours un numéro de ligne incorrect, ajoutez-y 7, comme dans la procédure stockée de la ligne 7, séparateur de lots est utilisé automatiquement. Donc, si vous utilisezselect Cast (Error_Number () + 7 en tant que Int) sous la forme [Error_Number] - vous obtiendrez la réponse souhaitée.

7
user2294834

Si vous utilisez un bloc catch et utilisez RAISERROR () pour toute validation de code dans le bloc try, la ligne d'erreur est alors signalée à l'emplacement du bloc catch et non à l'endroit où l'erreur réelle s'est produite. Je l'ai utilisé comme ça pour éclaircir ça.

BEGIN CATCH
  DECLARE @ErrorMessage NVARCHAR(4000);
  DECLARE @ErrorSeverity INT;
  DECLARE @ErrorState INT;

  SELECT 
     @ErrorMessage = ERROR_MESSAGE() + ' occurred at Line_Number: ' + CAST(ERROR_LINE() AS VARCHAR(50)),
     @ErrorSeverity = ERROR_SEVERITY(),
     @ErrorState = ERROR_STATE();

  RAISERROR (@ErrorMessage, -- Message text.
     @ErrorSeverity, -- Severity.
     @ErrorState -- State.
  );

END CATCH
5
Edward

tu peux utiliser ça 

CAST(ERROR_LINE() AS VARCHAR(50))

et si vous voulez créer une table de journal des erreurs, vous pouvez utiliser ceci:

INSERT INTO dbo.tbname( Source, Message) VALUES ( ERROR_PROCEDURE(), '[ ERROR_SEVERITY : ' + CAST(ERROR_SEVERITY() AS VARCHAR(50)) + ' ] ' + '[ ERROR_STATE : ' + CAST(ERROR_STATE() AS VARCHAR(50)) + ' ] ' + '[ ERROR_PROCEDURE : ' + CAST(ERROR_PROCEDURE() AS VARCHAR(50)) + ' ] ' + '[ ERROR_NUMBER : ' + CAST(ERROR_NUMBER() AS VARCHAR(50)) + ' ] ' +  '[ ERROR_LINE : ' + CAST(ERROR_LINE() AS VARCHAR(50)) + ' ] ' + ERROR_MESSAGE())
2
HAJJAJ

vous pouvez obtenir un message d'erreur et une ligne d'erreur dans catch block comme ceci:

'Ms Sql Server Error: - ' + ERROR_MESSAGE() + ' - Error occured at: ' + CONVERT(VARCHAR(20),  ERROR_LINE())
1
Badiparmagi

Dans TSQL/Procédures stockées

Vous pouvez obtenir une erreur telle que:

Msg 206, Niveau 16, Etat 2, Procédure myproc, Ligne 177 [Ligne de départ par lots 7]

Cela signifie que l'erreur est sur la ligne 177 dans le lot. Pas 177 dans le SQL. Vous devriez voir quel numéro de ligne votre lot commence, dans mon cas [7], puis vous ajoutez cette valeur au numéro de ligne pour trouver quelle instruction est fausse

1
jasttim

La réponse longue: le numéro de ligne est compté à partir de l'instruction CREATE PROCEDURE, plus les lignes vides ou les lignes de commentaire que vous avez pu avoir au-dessus lorsque vous avez exécuté l'instruction CREATE, mais sans compter les lignes précédant une instruction GO

Je trouvais beaucoup plus facile de créer un proc stocké pour vérifier:

GO

-- =============================================
-- Author:          <Author,,Name>
-- Create date: <Create Date,,>
-- Description:     <Description,,>
-- =============================================
CREATE PROCEDURE ErrorTesting
       -- Add the parameters for the stored procedure here
AS
BEGIN
       -- SET NOCOUNT ON added to prevent extra result sets from
       -- interfering with SELECT statements.
       SET NOCOUNT ON;

       -- Insert statements for procedure here
       SELECT 1/0

END
GO

Une fois que vous l'avez créé, vous pouvez le remplacer par ALTER PROCEDURE et ajouter des lignes vides au-dessus des commentaires et au-dessus et au-dessous de la première instruction GO pour voir l'effet. 

Une chose très étrange que j'ai remarquée est que j'ai dû exécuter EXEC ErrorTesting dans une nouvelle fenêtre de requête au lieu de le mettre en surbrillance au bas de la même fenêtre et de l'exécuter… Quand j'ai fait cela, les numéros de ligne ont continué à monter! Je ne sais pas pourquoi c'est arrivé ..

0
Andy Raddatz