2010-12-30 9 views
85

Kiedy używam serwera Sql i wystąpił błąd, komunikat o błędzie podaje numer wiersza, który nie ma żadnej korelacji z numerami wierszy w procedurze przechowywanej. Zakładam, że różnica wynika z białej przestrzeni i komentarzy, ale czy tak naprawdę jest?Jak uzyskać aktualny numer wiersza procedury składowanej z komunikatu o błędzie?

Jak powiązać te dwa zestawy numerów linii ze sobą? Jeśli ktokolwiek mógłby mi wskazać przynajmniej wskazówkę w odpowiednim kierunku, byłbym bardzo wdzięczny.

Używam serwera sql 2005.

TIA!

+1

Myślę, że numer linii odnosi się do treści proc. tj. zignoruj ​​nagłówek. –

+0

Może http://stackoverflow.com/questions/4550342/possible-to-get-the-line-of-the-current-executing-sproc-in-sql-server pomoże. –

+0

Gdzie kończy się nagłówek? Po rozpoczęciu, które następuje po procedurze zmiany ... AS? – chama

Odpowiedz

88

IIRC, rozpoczyna liczenie linii od początku partii, która utworzyła ten proces. Oznacza to albo początek skryptu, albo ostatnią instrukcję "GO" przed instrukcją create/alter proc.

Łatwiejszy sposób zobaczenia, jak wyciągnąć rzeczywisty tekst, który SQL Server użył podczas tworzenia obiektu. Przełączyć wyjście do trybu tekstowego (Ctrl-T z domyślnym odwzorowań przycisków) i uruchomić

sp_helptext proc_name 

Kopiuj wklej wyniki w oknie skryptu, aby uzyskać podświetlanie składni itp, i korzystać z funkcji Goto line (CTRL-G I think), aby przejść do zgłaszanej linii błędu.

+10

Kiedy zrobiłem to w trybie Grid-Output, utknęły one numery linii na zbyt – codeulike

+1

@ kodulike - Dobry punkt, jeśli użyjesz wyjścia Grid, numer wiersza będzie zgodny z numerem linii, więc nie musisz używać CTRL + G . Mój jedyny problem z wyjściem Grid polega na tym, że zmienia znaki TAB w pojedynczą SPACE, więc tracisz całe formatowanie. – Rick

2

można użyć tej

CAST(ERROR_LINE() AS VARCHAR(50)) 

i jeśli chcesz, aby tabeli dziennika błędów można użyć to:

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()) 
+4

Należy zauważyć, że ERROR_LINE() jest dostępny tylko w części CATCH TRY/CATCH w procedurze przechowywanej. Numer linii, który zgłasza, jest taki sam, jaki zwraca SQL Server, jeśli nie zauważysz błędu. Chociaż może to być przydatne, nie pomaga rozwiązać tego problemu. – Rick

7

Właściwie Error_number() działa bardzo dobrze.

Ta funkcja rozpoczyna się od ostatniej instrukcji GO (separator partii), więc jeśli nie użyto żadnych odstępów Go i wciąż wyświetla się niepoprawny numer wiersza - dodaj do niej 7, tak jak w procedurze przechowywanej w wierszu numer 7 separator wsadowy jest używany automatycznie. Więc jeśli użyjesz wybierz Cast (Error_Number() + 7 jako Int) jako [Error_Number] - otrzymasz pożądaną odpowiedź.

+5

Masz na myśli 'ERROR_LINE()', prawda? –

+0

'jeśli nie używałeś żadnych odstępów Go i nadal pokazuje nieprawidłowy numer linii - następnie dodaj do niego 7, ponieważ w procedurze przechowywanej w wierszu 7 separator wsadowy jest używany automatycznie. - co to miało oznaczać? –

0

Długa odpowiedź: numer linii jest liczona od rachunku CREATE PROCEDURE, plus wszelkie puste linie lub linie komentarz może mieli nad nim, kiedy rzeczywiście prowadził oświadczenie CREATE, ale nie licząc żadnych linii przed GO oświadczenie ...

Uważam, że znacznie łatwiej dokonać przechowywane proc, aby bawić się, aby potwierdzić:

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 

Po utworzeniu go, można przełączyć go do ALTER PROCEDURE i dodać kilka wierszy powyżej uwag i powyżej i poniżej pierwszego GO oświadczenie, aby zobaczyć efekt.

Jedną z bardzo dziwnych rzeczy, które zauważyłem było to, że musiałem uruchomić EXEC ErrorTesting w nowym oknie zapytań, zamiast podświetlać je na dole tego samego okna i uruchamiać ... Kiedy to robiłem, numery linii stale rosły! Nie wiem, dlaczego tak się stało.

16

Z przyzwyczajenia Umieszczam LINENO 0 bezpośrednio po BEGIN w moich procedurach przechowywanych. W tym przypadku resetuje numer linii - do zera.Następnie po prostu dodaj numer linii zgłoszony przez komunikat o błędzie do numeru linii w SSMS, gdzie napisałeś LINENO 0 i bingo - numer wiersza błędu jest reprezentowany w oknie zapytania.

1

można dostać komunikat o błędzie i linii błędu w bloku catch tak:

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

Jeśli używasz blok catch i używane RAISERROR() dla każdej walidacji kodu w obrębie bloku try to linia Błąd dostaje zgłasza, gdzie znajduje się Blokada połowu, a nie tam, gdzie wystąpił prawdziwy błąd. Użyłem tego w ten sposób, aby to wyjaśnić.

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 
Powiązane problemy