Como posso obter o número real da linha do procedimento armazenado em uma mensagem de erro?

110

Quando eu uso o SQL Server e há um erro, a mensagem de erro fornece um número de linha que não tem correlação com os números de linha no procedimento armazenado. Presumo que a diferença se deva ao espaço em branco e aos comentários, mas é mesmo?

Como posso relacionar esses dois conjuntos de números de linha entre si? Se alguém pudesse me dar pelo menos uma indicação na direção certa, eu realmente apreciaria.

Estou usando o SQL server 2005.

chama
fonte
1
Acho que o número da linha está relacionado ao corpo do proc. ou seja, ignore o cabeçalho.
Martin Smith
Talvez stackoverflow.com/questions/4550342/… ajude.
John Saunders
Onde termina o cabeçalho? Após o início segue-se o procedimento de alteração ... AS?
chama
Pareceu começar a contar a partir da create proclinha em meu teste. Presumo que você esteja vendo algo diferente.
Martin Smith
1
Descrito em minha resposta aqui: stackoverflow.com/questions/2947173/…
gbn

Respostas:

113

IIRC, ele começa a contar linhas desde o início do lote que criou aquele proc. Isso significa o início do script ou então a última instrução "GO" antes da instrução create / alter proc.

Uma maneira mais fácil de ver isso é puxar o texto real que o SQL Server usou ao criar o objeto. Mude sua saída para o modo de texto (CTRL-T com os mapeamentos de teclas padrão) e execute

sp_helptext proc_name

Copie e cole os resultados em uma janela de script para obter o realce da sintaxe, etc., e use a função goto line (CTRL-G, eu acho) para ir para a linha de erro relatada.

Rick
fonte
14
Quando fiz isso no modo Grid-Output, ele prendeu os números das linhas também
codeulike
2
@codeulike - Bom ponto, se você usar a saída do Grid, o número da linha corresponderá ao número da linha, então você não precisa usar CTRL + G. Meu único problema com a saída do Grid é que ele muda os caracteres TAB para um único ESPAÇO, então você perde toda a formatação.
Rick
32

Por hábito, coloco LINENO 0logo depois BEGINem meus procedimentos armazenados. Isso redefine o número da linha - para zero, neste caso. Em seguida, basta adicionar o número da linha relatado pela mensagem de erro ao número da linha no SSMS onde você escreveu LINENO 0e bingo - você tem o número da linha do erro conforme representado na janela de consulta.

Vorlic
fonte
4
Por que não apenas colocar "LineNo X", onde X = o número da linha em que você colocou a instrução, para que seja automaticamente adicionado ao número da linha relatada?
LarryBud
8

Se você usar um Catch Block e um RAISERROR () para qualquer validação de código dentro do Try Block, a linha de erro será relatada onde o Catch Block está e não onde o erro real ocorreu. Eu usei assim para esclarecer isso.

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
fonte
6

Na verdade, isso Error_number()funciona muito bem.

Esta função inicia contagens a partir da última instrução GO (separador de lote), então se você não usou nenhum espaço Go e ainda está mostrando um número de linha errado - então adicione 7 a ele, como no procedimento armazenado na linha número 7 o separador de lote é usado automaticamente. Portanto, se você usar selecionar Cast (Error_Number () + 7 como Int) como [Error_Number] - você obterá a resposta desejada.

user2294834
fonte
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.- o que isso queria dizer?
sublinhado_d
4

Em TSQL / procedimentos armazenados

Você pode obter um erro como:

Msg 206, Nível 16, Estado 2, Procedimento myproc, Linha 177 [Batch Start Line 7]

Isso significa que o erro está na linha 177 do lote. Não 177 no SQL. Você deve ver em qual número de linha seu lote começa, no meu caso [7], e então você adiciona esse valor ao número da linha para descobrir qual declaração está errada

Jasttim
fonte
2

você pode usar isso

CAST(ERROR_LINE() AS VARCHAR(50))

e se você quiser fazer uma tabela de log de erros, você pode usar isto:

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
fonte
4
Observe que ERROR_LINE () está disponível apenas na parte CATCH de um TRY / CATCH dentro do procedimento armazenado. O número da linha que ele informa é o mesmo que o SQL Server retorna se você não detectar o erro. Portanto, embora isso possa ser útil, não ajuda a resolver esta questão.
Rick
1

A resposta longa: o número da linha é contado a partir da CREATE PROCEDUREdeclaração, mais quaisquer linhas em branco ou linhas de comentário que você possa ter colocado acima quando executou a CREATEdeclaração, mas sem contar as linhas antes de umGO declaração ...

Achei muito mais fácil fazer um procedimento armazenado para testar e confirmar:

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

Depois de criá-lo, você pode alternar para ALTER PROCEDUREe adicionar algumas linhas em branco acima dos comentários e acima e abaixo do primeiroGO instrução para ver o efeito.

Uma coisa muito estranha que notei foi que tive que correr EXEC ErrorTesting em uma nova janela de consulta em vez de realçá-la na parte inferior da mesma janela e executar ... Quando fiz isso, os números das linhas continuaram aumentando! Não tenho certeza por que isso aconteceu ..

Andy Raddatz
fonte
1

você pode obter a mensagem de erro e a linha de erro no bloco catch como este:

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