Wie kann ich die tatsächliche Zeilennummer der gespeicherten Prozedur aus einer Fehlermeldung abrufen?

110

Wenn ich SQL Server verwende und ein Fehler auftritt, gibt die Fehlermeldung eine Zeilennummer an, die nicht mit den Zeilennummern in der gespeicherten Prozedur korreliert. Ich gehe davon aus, dass der Unterschied auf Leerzeichen und Kommentare zurückzuführen ist, aber ist es wirklich so?

Wie kann ich diese beiden Sätze von Zeilennummern miteinander in Beziehung setzen? Wenn mir jemand wenigstens einen Hinweis in die richtige Richtung geben könnte, würde ich es wirklich schätzen.

Ich verwende SQL Server 2005.

Chama
quelle
1
Ich denke, die Zeilennummer bezieht sich auf den Körper des Prozesses. dh den Header ignorieren.
Martin Smith
Wo endet der Header? Nach dem Beginn folgt das Änderungsverfahren ... AS?
Chama
Es schien create procin meinem Test von der Linie zu zählen . Ich nehme an, Sie sehen etwas anderes.
Martin Smith
1
Beschrieben in meiner Antwort hier: stackoverflow.com/questions/2947173/…
gbn

Antworten:

113

IIRC beginnt mit dem Zählen der Zeilen ab dem Beginn des Stapels, der diesen Prozess erstellt hat. Dies bedeutet entweder den Start des Skripts oder die letzte "GO" -Anweisung vor der Anweisung create / alter proc.

Eine einfachere Möglichkeit, dies zu erkennen, besteht darin, den tatsächlichen Text abzurufen, den SQL Server beim Erstellen des Objekts verwendet hat. Schalten Sie Ihre Ausgabe in den Textmodus (STRG-T mit den Standardtastenzuordnungen) und führen Sie sie aus

sp_helptext proc_name

Kopieren Sie die Ergebnisse, fügen Sie sie in ein Skriptfenster ein, um Syntaxhervorhebungen usw. zu erhalten, und verwenden Sie die Funktion goto line (STRG-G, glaube ich), um zur gemeldeten Fehlerzeile zu gelangen.

Rick
quelle
14
Als ich dies im Grid-Output-Modus tat, klebte es auch die Zeilennummern an
codeulike
2
@codeulike - Guter Punkt, wenn Sie die Rasterausgabe verwenden, stimmt die Zeilennummer mit der Zeilennummer überein, sodass Sie STRG + G nicht verwenden müssen. Mein einziges Problem bei der Rasterausgabe besteht darin, dass TAB-Zeichen in ein einzelnes Leerzeichen geändert werden, sodass Sie die gesamte Formatierung verlieren.
Rick
32

Aus Gewohnheit lege ich LINENO 0direkt danach BEGINin meine gespeicherten Prozeduren. Dies setzt die Zeilennummer zurück - in diesem Fall auf Null. Fügen Sie dann einfach die von der Fehlermeldung gemeldete Zeilennummer zur Zeilennummer in SSMS hinzu, in die Sie geschrieben haben, LINENO 0und Bingo - Sie haben die Zeilennummer des Fehlers, wie im Abfragefenster dargestellt.

Vorlic
quelle
4
Warum setzen Sie nicht einfach "LineNo X", wobei X = die Zeilennummer ist, auf die Sie die Anweisung setzen, damit sie automatisch zur gemeldeten Zeilennummer hinzugefügt wird?
LarryBud
8

Wenn Sie einen Catch Block verwenden und RAISERROR () für eine Codeüberprüfung innerhalb des Try Blocks verwenden, wird die Fehlerzeile dort gemeldet, wo sich der Catch Block befindet und nicht dort, wo der tatsächliche Fehler aufgetreten ist. Ich habe es so benutzt, um das zu klären.

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
Edward
quelle
6

Eigentlich Error_number()funktioniert das sehr gut.

Diese Funktion startet die Zählung ab der letzten GO-Anweisung (Batch Separator). Wenn Sie also keine Go-Leerzeichen verwendet haben und immer noch eine falsche Zeilennummer angezeigt wird, fügen Sie 7 hinzu, wie in der gespeicherten Prozedur in Zeile 7 des Batch-Separators wird automatisch verwendet. Wenn Sie also Cast (Error_Number () + 7 als Int) als [Error_Number] auswählen, erhalten Sie die gewünschte Antwort.

user2294834
quelle
1
if you have not used any Go spaces and it is still showing a wrong line number - then add 7 to it, as in stored procedure in line number 7 the batch separator is used automatically.- Was sollte das heißen?
underscore_d
4

In TSQL / Gespeicherte Prozeduren

Möglicherweise erhalten Sie eine Fehlermeldung wie:

Meldung 206, Ebene 16, Status 2, Prozedur myproc, Zeile 177 [Stapelstartzeile 7]

Dies bedeutet, dass sich der Fehler in Zeile 177 im Stapel befindet. Nicht 177 in der SQL. Sie sollten sehen, mit welcher Zeilennummer Ihr Stapel beginnt, in meinem Fall [7], und dann diesen Wert zur Zeilennummer hinzufügen, um festzustellen, welche Anweisung falsch ist

jasttim
quelle
2

Sie können dies verwenden

CAST(ERROR_LINE() AS VARCHAR(50))

und wenn Sie eine Fehlerprotokolltabelle erstellen möchten, können Sie Folgendes verwenden:

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())
HAJJAJ
quelle
4
Beachten Sie, dass ERROR_LINE () nur im CATCH-Teil eines TRY / CATCH innerhalb der gespeicherten Prozedur verfügbar ist. Die gemeldete Zeilennummer ist dieselbe, die SQL Server zurückgibt, wenn Sie den Fehler nicht abfangen. Das kann zwar nützlich sein, hilft aber nicht, diese Frage zu lösen.
Rick
1

Die lange Antwort: Die Zeilennummer wird aus der CREATE PROCEDUREAnweisung gezählt, plus alle Leerzeilen oder Kommentarzeilen, die Sie möglicherweise darüber hatten, als Sie die CREATEAnweisung tatsächlich ausgeführt haben , aber keine Zeilen vor einer GOAnweisung gezählt haben…

Ich fand es viel einfacher, einen gespeicherten Prozess zum Herumspielen zu erstellen, um Folgendes zu bestätigen:

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

Nachdem Sie es erstellt haben, können Sie es ändern ALTER PROCEDUREund einige leere Zeilen über den Kommentaren und über und unter der ersten GOAnweisung hinzufügen , um den Effekt zu sehen.

Eine sehr seltsame Sache, die mir auffiel, war, dass ich EXEC ErrorTestingin einem neuen Abfragefenster laufen musste, anstatt es am unteren Rand desselben Fensters hervorzuheben und zu laufen ... Als ich das tat, stiegen die Zeilennummern weiter an! Ich bin mir nicht sicher, warum das passiert ist.

Andy Raddatz
quelle
1

Sie können Fehlermeldung und Fehlerzeile in catch-Block wie folgt erhalten:

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