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!
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.
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.
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.
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
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())
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())
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
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é ..