Як я можу отримати фактично збережений номер рядка процедури з повідомлення про помилку?


110

Коли я використовую SQL Server і є помилка, повідомлення про помилку дає номер рядка, який не має кореляції з номерами рядків у збереженій процедурі. Я припускаю, що різниця пояснюється білим простором та коментарями, але чи це насправді?

Як я можу пов'язати ці два набори номерів рядків один з одним? Якщо хтось міг би дати мені хоча б вказівник у правильному напрямку, я дуже вдячний.

Я використовую SQL-сервер 2005 року.


1
Я думаю, що номер рядка стосується тіла проц. тобто ігноруйте заголовок.
Мартін Сміт


Де закінчується заголовок? Після початку, що слідує за процедурою зміни ... AS?
чама

Здавалося, я починаю рахувати з create procрядка в моєму тесті. Я припускаю, що ви бачите щось інше.
Мартін Сміт

1
Описане в моїй обороні тут: stackoverflow.com/questions/2947173 / ...
ГБН

Відповіді:


113

IIRC, він починає рахувати рядки з початку партії, яка створила цю процедуру. Це означає або початок сценарію, або інший останній оператор "GO" перед оператором create / alter proc.

Найпростіший спосіб зрозуміти це - витягнути фактичний текст, який використовував SQL Server при створенні об'єкта. Переключіть свій вихід у текстовий режим (CTRL-T із відображенням ключових відображень за замовчуванням) та запустіть

sp_helptext proc_name

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


14
Коли я робив це в режимі Grid-Output, він також наклеював номери рядків
кодоподібно

2
@codeulike - Добре, якщо ви використовуєте Grid висновок, номер рядка буде відповідати номеру рядка, тому вам не потрібно використовувати CTRL + G. Моя єдина проблема з виведенням Grid - це те, що він змінює символи TAB на єдиний пробіл, тому ви втрачаєте все форматування.
Рік

32

По звичці я розміщую LINENO 0безпосередньо після BEGINсвоїх зберігаються процедур. Це скидає номер рядка - до нуля, в цьому випадку. Потім просто додайте номер рядка, повідомлений у повідомленні про помилку, до номера рядка в SSMS, де ви написали LINENO 0та бінго - у вас є номер рядка помилки, як показано у вікні запиту.


4
Чому б просто не поставити "LineNo X", де X = номер рядка, на який ви ставите виписку, так що він автоматично додається до звітованого номера рядка?
LarryBud

8

Якщо ви використовуєте блок лову і використовували RAISERROR () для будь-якої перевірки коду в блоці спробу, тоді про рядку помилок повідомляється, де знаходиться блок блоку, а не там, де сталася реальна помилка. Я використовував це так, щоб очистити це.

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

6

Насправді це Error_number()працює дуже добре.

Ця функція починає рахуватися з останнього оператора GO (Batch Separator), тому якщо ви не використовували пропусків Go, і він все ще показує неправильний номер рядка - тоді додайте 7 до нього, як у збереженій процедурі в рядку № 7 пакетного роздільника використовується автоматично. Отже, якщо ви будете використовувати [Caror (Error_Number () + 7 як Int) як [Error_Number], ви отримаєте бажану відповідь.


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.- що це мало означати?
підкреслюйте_d

4

У процедурах TSQL / Зберігаються

Ви можете отримати помилку, наприклад:

Msg 206, рівень 16, стан 2, процедура myproc, рядок 177 [рядок початку серії 7]

Це означає, що помилка знаходиться в рядку 177 в партії. Не 177 у SQL. Ви повинні побачити, на якому номері рядка починається ваша партія, в моєму випадку [7], а потім ви додасте це значення до номера рядка, щоб знайти, яке твердження неправильне


2

Ви можете використовувати це

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

4
Зауважте, що ERROR_LINE () доступний лише у частині CATCH TRY / CATCH у межах збереженої процедури. Номер рядка, про який він повідомляє, той самий, що і SQL Server повертає, якщо ви не виявите помилку. Тож як це може бути корисним, це не допомагає вирішити це питання.
Рік

1

Довга відповідь: номер рядка обчислюється з 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в новому вікні запитів, а не виділяти його внизу того ж вікна і бігати… Коли я це зробив, то номери рядків продовжували зростати! Не впевнений, чому так сталося ..


1

ви можете отримати повідомлення про помилку та рядок помилок у блоці уловки, як це:

'Ms Sql Server Error: - ' + ERROR_MESSAGE() + ' - Error occured at: ' + CONVERT(VARCHAR(20),  ERROR_LINE())
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.