Как я могу получить фактический номер строки хранимой процедуры из сообщения об ошибке?

Когда я использую SQL Server и возникает ошибка, в сообщении об ошибке указывается номер строки, который не имеет корреляции с номерами строк в хранимой процедуре. Я предполагаю, что разница связана с пробелами и комментариями, но так ли это на самом деле?

Как я могу связать эти два набора номеров строк друг с другом? Если бы кто-нибудь мог дать мне хотя бы указатель в правильном направлении, я был бы очень признателен.

Я использую SQL Server 2005

Ответ 1

IIRC, он начинает подсчет строк с начала партии, которая создала этот proc. Это означает либо начало script, либо последнего оператора GO в предложении create/alter proc.

Более простой способ увидеть это, чтобы вытащить фактический текст, который SQL Server использовал при создании объекта. Переключите вывод в текстовый режим (CTRL-T с сопоставлениями по умолчанию) и запустите

sp_helptext proc_name

Скопируйте полученные результаты в окно script, чтобы получить подсветку синтаксиса и т.д., и используйте функцию линии goto (CTRL-G, я думаю), чтобы перейти к сообщенной строке ошибок.

Ответ 2

По привычке я помещаю LINENO 0 непосредственно после BEGIN в мои хранимые процедуры. В этом случае сбрасывается номер строки - до нуля. Затем просто добавьте номер строки, сообщенный сообщением об ошибке, на номер строки в SSMS, где вы написали LINENO 0 и bingo - у вас есть номер строки ошибки, представленный в окне запроса.

Ответ 3

На самом деле это Error_number() работает очень хорошо.

Эта функция запускает отсчеты из последнего оператора GO (пакетного разделителя), поэтому, если вы не использовали пробелы Go и пока не указали неправильный номер строки, затем добавьте 7 к нему, как в хранимой процедуре в строке 7 сепаратор партии используется автоматически. Поэтому, если вы используете выберите Cast (Error_Number() + 7 as Int) как [Error_Number] - вы получите желаемый ответ.

Ответ 4

Если вы используете Catch Block и используете RAISERROR() для любой проверки кода в блоке Try, тогда появляется строка Error, где находится Catch Block, а не где произошла реальная ошибка. Я использовал его так, чтобы очистить это.

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

вы можете использовать этот

CAST(ERROR_LINE() AS VARCHAR(50))

и если вы хотите создать таблицу журнала ошибок, вы можете использовать это:

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

Ответ 6

Длинный ответ: номер строки подсчитывается из оператора CREATE PROCEDURE плюс любые пустые строки или строки комментариев, которые вы могли иметь над ним, когда вы фактически запускали оператор CREATE, но не считали строки до GO...

Мне было гораздо проще сделать хранимую процедуру для воспроизведения, чтобы подтвердить:

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

После того, как вы его создали, вы можете переключить его на ALTER PROCEDURE и добавить несколько пустых строк над комментариями и выше и ниже первого оператора GO, чтобы увидеть эффект.

Одна очень странная вещь, которую я заметил, заключалась в том, что мне пришлось запускать EXEC ErrorTesting в новом окне запроса, а не выделять ее внизу того же окна и работать... Когда я это делал, номера строк продолжали расти! Не знаю, почему это произошло.

Ответ 7

вы можете получить сообщение об ошибке и строку ошибки в блоке catch следующим образом:

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

Ответ 8

В TSQL/Хранимых процедурах

Вы можете получить ошибку, такую как:

Msg 206, Level 16, State 2, Procedure myproc, Line 177 [Batch Start Line 7]

Это означает, что ошибка находится в строке 177 в пакете. Не 177 в SQL. Вы должны увидеть, с какого номера строки начинается ваш пакет, в моем случае [7], а затем вы добавляете это значение к номеру строки, чтобы найти, какое утверждение неверно