Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Обработка исключений  [new]
mezzanine
Member

Откуда:
Сообщений: 157
Добрый день.

Есть процедура p_main
CREATE PROCEDURE dbo.p_main (
  @result NVARCHAR(100) OUTPUT,
  @error NVARCHAR(1000) OUTPUT
)
AS
BEGIN TRY
  ...
  EXEC p_proc_1;
  ...
BEGIN CATCH
  IF (@result IS NULL)
    SET @result = 'SYSTEM.ERROR';
  SET @error = '[' + ERROR_PROCEDURE() + '][' + CONVERT(NVARCHAR, ERROR_LINE()) + ']:' + ERROR_MESSAGE();
END CATCH


В ней вызывается процедура p_proc_1. В этой процедуре нет блока TRY..CATCH, только вызывается исключение "THROW 50000, 'Test error from NESTED procedure!', 1;".

Как в блоке TRY..CATCH процедуры p_main получить номер строки не только процедуры p_proc_1 но и номер строки где она была вызвана?

Можно конечно вызов процедуры завернуть в TRY..CATCH обработать и еще раз вызвать исключение, но может есть другие варианты.
21 дек 15, 13:09    [18588122]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
mezzanine
Member

Откуда:
Сообщений: 157
mezzanine,

Может кому то будет интересно: Microsoft SQL Server Call Stack: Adding The Missing Oracle Feature

Но как пишет товарищ открыта заявка с 2005 года Provide function to retrieve the entire call stack и обещают добавить в 2014 версии.
21 дек 15, 13:30    [18588257]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
mezzanine, дарю шаблон процедуры.
SET ANSI_NULLS, QUOTED_IDENTIFIER ON
GO
/*
Назначение:
Автор:
Дата создания:
*/
CREATE PROCEDURE [schema].[name]
@param1 int -- внести описание параметра
AS
BEGIN

SET NOCOUNT ON;
BEGIN TRY
	DECLARE @trancnt int = @@trancount;

	/*Написать код процедуры*/

END TRY
BEGIN CATCH
	IF @trancnt = 0 and @@trancount > 0
		ROLLBACK;
	DECLARE 
		@ErrorText varchar(max) = ERROR_MESSAGE(), 
		@State tinyint = ERROR_STATE();
	IF ERROR_NUMBER() < 50000 or @State = 255 -- Для системной ошибки показать цепочку вызова процедур, @State=255 признак системной ошибки
	BEGIN
		SET @ErrorText = concat(@ErrorText,' ПРОЦ:',error_procedure(),', СТРК:',error_line(),'; ');
		SET @State = 255
	END;
	THROW 50000, @ErrorText, @State;
END CATCH

END
GO
21 дек 15, 13:42    [18588313]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
mezzanine
mezzanine,

Может кому то будет интересно: Microsoft SQL Server Call Stack: Adding The Missing Oracle Feature

Но как пишет товарищ открыта заявка с 2005 года Provide function to retrieve the entire call stack и обещают добавить в 2014 версии.
2014-я - старьё!
Уже -версии 2016-го выходят...
21 дек 15, 14:14    [18588502]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Владислав Колосов
mezzanine, дарю шаблон процедуры.
SET ANSI_NULLS, QUOTED_IDENTIFIER ON
GO
/*
Назначение:
Автор:
Дата создания:
*/
CREATE PROCEDURE [schema].[name]
@param1 int -- внести описание параметра
AS
BEGIN

SET NOCOUNT ON;
BEGIN TRY
	DECLARE @trancnt int = @@trancount;

	/*Написать код процедуры*/

END TRY
BEGIN CATCH
	IF @trancnt = 0 and @@trancount > 0
		ROLLBACK;
	DECLARE 
		@ErrorText varchar(max) = ERROR_MESSAGE(), 
		@State tinyint = ERROR_STATE();
	IF ERROR_NUMBER() < 50000 or @State = 255 -- Для системной ошибки показать цепочку вызова процедур, @State=255 признак системной ошибки
	BEGIN
		SET @ErrorText = concat(@ErrorText,' ПРОЦ:',error_procedure(),', СТРК:',error_line(),'; ');
		SET @State = 255
	END;
	THROW 50000, @ErrorText, @State;
END CATCH

END
GO



оффтопег.
IF @trancnt = 0 and @@trancount > 0
ROLLBACK;

Но могли зайти с @@trancount>0, затем внутри @@trancount++
21 дек 15, 14:19    [18588535]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
mezzanine
Member

Откуда:
Сообщений: 157
Владислав Колосов,

У меня проблема в том что error_line() содержит номер строки последней ошибки. В случае вложенных вызовов процедур видно только где там в глубине была ошибка, а хотелось бы еще знать номер строки в вызывающей процедуре.
21 дек 15, 14:20    [18588541]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
Konst_One
Member

Откуда:
Сообщений: 11621
mezzanine
Владислав Колосов,

У меня проблема в том что error_line() содержит номер строки последней ошибки. В случае вложенных вызовов процедур видно только где там в глубине была ошибка, а хотелось бы еще знать номер строки в вызывающей процедуре.


пробрасывате этот номер через все процедуры наверх в качестве параметра
21 дек 15, 14:26    [18588598]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
aleks2
Guest
mezzanine
В случае вложенных вызовов процедур видно только где там в глубине была ошибка, а хотелось бы еще знать номер строки в вызывающей процедуре.


Как скромны ваши желания.
Надо уж требовать сразу исправления ошибки. Шоб ее ваще не было.
21 дек 15, 14:30    [18588625]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8805
mezzanine,

этот обработчик необходимо установить в каждой процедуре.


Но могли зайти с @@trancount>0, затем внутри @@trancount++

Именно. Откат возлагается на инициатора всей цепочки и ошибка проталкивается наверх вместе с цепочкой вызова.
21 дек 15, 15:34    [18589196]     Ответить | Цитировать Сообщить модератору
 Re: Обработка исключений  [new]
mezzanine
Member

Откуда:
Сообщений: 157
Владислав Колосов,

Спасибо. Получается @ErrorText будет содержать самодельный стек вызова. Но, в взывающей процедуре (откуда начался стек вызова) все равно не обойтись без повторного вызова исключения.
21 дек 15, 15:42    [18589249]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить