Published on

October 21, 2008

Как захватить описания ошибок в хранимых процедурах SQL Server

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

В этой статье мы рассмотрим решение этой проблемы, используя журнал ошибок SQL Server и хранимую процедуру sp_altermessage.

Проблема

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

Некоторые SQL-специалисты предложили использовать DBCC OUTPUTBUFFER или процедуры sp_Oa с динамическим SQL и SQL-DMO для захвата сообщений об ошибках. Однако эти подходы могут быть ненадежными или чрезмерно сложными.

Решение

При изучении таблицы sysmessages я наткнулся на хранимую процедуру sp_altermessage. Эта процедура позволяет администратору базы данных настроить регистрацию ошибок в журнале ошибок SQL Server. Это дало мне идею: настроить регистрацию наиболее вероятных ошибок и затем прочитать их из журнала ошибок.

Например, я настроил ошибки 515, 547, 2601, 2627 и 3902 для самозаписи с помощью sp_altermessage. Это означает, что каждый раз, когда происходит нарушение ограничения (например, первичного ключа, внешнего ключа, not null или уникального ограничения), ошибка регистрируется в журнале ошибок SQL.

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

Set xact_abort off  -- требуется !
Declare @intError INT
Declare @VcDescr VARCHAR(1000)
Insert testtable (PkId ) select null  -- ожидаемая ошибка, как указано выше
Select @intError =  @@ERROR
If @intError <> 0
 Begin
        Exec GetErrorStringSP @intError, @VcDescr OUTPUT
        Print @VcDescr
 End

Выполнив приведенный выше код, вы можете получить описание ошибки для последней ошибки, которая произошла с указанным номером ошибки.

Соображения

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

  • Вам нужно включить настройки на уровне сервера для включения регистрации, что может быть немного проблематично для SQL.
  • Включение регистрации может быстро увеличить размер журнала ошибок SQL. Рассмотрите возможность увеличения общего количества журналов ошибок для системы и реализации задания для циклического удаления журналов ошибок SQL ежедневно.
  • Возможно, вам потребуется предоставить права не-администратору для выполнения xp_readerrorlog.
  • Если происходит ошибка и регистрация отключена после этой ошибки, хранимая процедура будет продолжать выдавать то же описание ошибки, что и предыдущая. Рассмотрите возможность реализации логики выбора ошибок в определенный промежуток времени, если это необходимо.

Несмотря на эти соображения, этот подход доказал свою эффективность в соответствии с требованиями проекта и может быть полезен для SQL-специалистов, сталкивающихся с подобными проблемами.

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

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.