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

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

2 хранимые процедуры, первая вызывает вторую... если во второй процедуре в конструкции TRY..CATCH возникает ошибка, идёт её обработка и описание ошибки возвращается через RAISERROR в блоке CATCH.

Вопрос, можно ли каким-то образом текст ошибки получить в первой хранимой процедуре (которая вызвала вторую) передав её в переменную?
25 дек 18, 09:59    [21772688]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
uaggster
Member

Откуда:
Сообщений: 811
Игорь_UUS, https://habr.com/post/358936/
:-)
Ну, перед тем, как читать MSDN.
25 дек 18, 10:43    [21772723]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7671
Игорь_UUS,

почему в переменную? Исключение надо передавать на самый верхний уровень. Используйте Throw.
25 дек 18, 12:09    [21772810]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 670
Владислав Колосов
Игорь_UUS,

почему в переменную? Исключение надо передавать на самый верхний уровень. Используйте Throw.


Throw не могу т.к. mssql2008
25 дек 18, 12:27    [21772835]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7671
Игорь_UUS,

попробуйте в сочетании с SET XACT_ABORT = ON, у меня нет 2008, чтобы проверить.
25 дек 18, 12:34    [21772843]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 670
Владислав Колосов,

Дело даже не в этом... есть костыль для api...

Я бы сказал ответ верхнему ПО идёт по 2-м разным сценариям, в одном случае это десктоповое приложение, которое как раз таки обрабатывает ошибки как надо, и есть api, модули на php. Но вот обработка ошибок там идёт не так "как надо" в виде передачи ошибки в возвращаемую переменную.

А бизнес логика одна... т.е. интерфейсные хранимые процедуры десктоповой программы и интерфнйсные процедуры для api используют одни и те же процедуры бизнес логике. Информирование об ошибках (или уведомление) верхнему ПО идёт через RAISERROR и кода RETURN самой процедуры (если код = 0, то обработка прошла успешна). И получается, если по линии api идёт что-то не так, то как мне отловить то что было передано в "недрах бизнес логике" через RAISERROR
25 дек 18, 13:08    [21772884]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7671
Игорь_UUS,

для реализации API обычно пишут процедуры - обертки, там простой SELECT ERROR_MESSAGE() в блоке CATCH.
25 дек 18, 16:28    [21773122]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Ennor Tiegael
Member

Откуда:
Сообщений: 3237
Игорь_UUS,

Output variables можно использовать:
create procedure dbo.Proc1
(
  ...
  @Error int = null output,
  @Message nvarchar(2048) = null output
)
as
...
begin catch

if nullif(@Error, 0) is null
  select @Error = error_number(), @Message = error_message();

...
end catch;
return;
go
Если такие параметры есть по всему стеку вызовов, то передать ошибку на самый верх можно безо всяких RAISERROR или THROW. Главное, не забывать добавлять output к этим параметрам при вызове из других хранимок. Ну и с транзакциями аккуратнее, следите за значением @@trancount (не забываем, что в сиквеле вложенных транзакций нет) и состоянием set xact_abort.
25 дек 18, 17:11    [21773154]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 670
Владислав Колосов
Игорь_UUS,

для реализации API обычно пишут процедуры - обертки, там простой SELECT ERROR_MESSAGE() в блоке CATCH.



Но CATCH ловит только те сообщения, которые имеют уровень серьёзности более 10. В этом случае десктоповое приложение "кидает" исключение (так работает компонент FireDAC... уфф и это правильно)... тут придётся переделывать очень много, так сказать обернуть "верхние уровни" бизнес логики в блок CATCH и переориентировать ошибку в низкий уровень серьёзности...

я правильно понимаю, то что сообщения с уровнем серьёзности менее 11 перехватить или прочитать невозможно? т.е. таких методов в самом mssql нет?
26 дек 18, 08:53    [21773564]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 5926
Игорь_UUS
я правильно понимаю, то что сообщения с уровнем серьёзности менее 11 перехватить или прочитать невозможно? т.е. таких методов в самом mssql нет?

RAISERROR c severity<=10 - это, по сути, обычные текстовые сообщения. Их вполне прекрасно можно прочитать в клиентском приложении (например, вот так, или вот так).
26 дек 18, 09:34    [21773580]     Ответить | Цитировать Сообщить модератору
 Re: Использование сообщения RAISERROR  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 670
Сон Веры Павловны
Игорь_UUS
я правильно понимаю, то что сообщения с уровнем серьёзности менее 11 перехватить или прочитать невозможно? т.е. таких методов в самом mssql нет?

RAISERROR c severity<=10 - это, по сути, обычные текстовые сообщения. Их вполне прекрасно можно прочитать в клиентском приложении (например, вот так, или вот так).


В десктоповом приложении как раз таки полный порядок с "обычными сообщениями" (перехватываю и читаю)... а вот в "обёртках" для API - нет

вопрос можно ли их перехватить в бизнес логике MSSQL?
26 дек 18, 10:52    [21773663]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить