Как я могу получить фактический номер строки хранимой процедуры из сообщения об ошибке?
Когда я использую 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], а затем вы добавляете это значение к номеру строки, чтобы найти, какое утверждение неверно