Реализация структурированной обработки исключений

Завершено

Теперь, когда у вас есть представление о характере ошибок и базовой обработке ошибок в T-SQL, пришло время взглянуть на более расширенную форму обработки ошибок. Структурированная обработка исключений появилась в SQL Server 2005.

Здесь вы узнаете, как использовать его и оценить свои преимущества и ограничения, включая блок TRY CATCH, роль функций обработки ошибок и понимание разницы между перехватываемыми и неуловимыми ошибками. Наконец, вы увидите, как можно управлять ошибками и отображать их при необходимости.

Что такое использование блоков TRY/CATCH в программировании

Структурированная обработка исключений более эффективна, чем обработка ошибок на основе системной переменной @@ERROR. Это позволяет предотвратить засорение кода обработкой ошибок и централизовать обработку ошибок. Централизация кода обработки ошибок также означает, что вы можете сосредоточиться больше на цели кода, а не на обработке ошибок, содержащихся в ней.

Блок TRY и блок CATCH

При использовании структурированной обработки исключений код, который может вызвать ошибку, помещается в блок TRY. Блоки TRY заключены в инструкции BEGIN TRY и END TRY .

Если возникает перехватываемая ошибка — а большинство ошибок можно перехватить — управление выполнением переходит в блок CATCH. Блок CATCH — это ряд инструкций T-SQL, заключенных в инструкции BEGIN CATCH и END CATCH .

Замечание

Хотя BEGIN CATCH и END TRY являются отдельными инструкциями, BEGIN CATCH должен сразу следовать за END TRY.

Текущие ограничения

Высокоуровневые языки часто предлагают конструкцию try/catch/finally и часто используются для освобождения ресурсов неявно. В T-SQL нет эквивалентного блока FINALLY.

Понимание разницы между перехватываемыми и неперехватываемыми ошибками

Важно понимать, что в то время как блоки TRY/CATCH позволяют перехватывать гораздо более широкий диапазон ошибок, чем можно с помощью @@ERROR, вы не можете поймать каждый тип.

Перехватываемые и неперехватываемые ошибки

Не все ошибки могут быть пойманы блоками TRY/CATCH в той же области, где существует блок TRY/CATCH. Часто ошибки, которые не могут быть обнаружены в том же контексте, могут быть обнаружены во внешнем контексте. Например, вы не сможете поймать ошибку в хранимой процедуре, содержащей блок TRY/CATCH. Однако вы, скорее всего, перехватите эту ошибку в блоке TRY/CATCH в коде, который вызвал хранимую процедуру, в которой произошла ошибка.

Распространенные неперехватываемые ошибки

Распространенные примеры неконтролируемых ошибок:

  • Ошибки, такие как синтаксические ошибки, которые препятствуют компиляции пакета.
  • Проблемы перекомпиляции на уровне выражений, которые обычно касаются отложенного разрешения имен. Например, можно создать хранимую процедуру, которая ссылается на неизвестную таблицу. Ошибка возникает только в том случае, если процедура пытается разрешить имя таблицы в objectid.

Как перезабросить ошибки с помощью THROW

Если инструкция THROW используется в блоке CATCH без каких-либо параметров, она повторно вызовет ошибку, которая вызвала вход в блок CATCH. Этот метод можно использовать для реализации ведения журнала ошибок в базе данных путем перехвата ошибок и ведения журнала их сведений, а затем выдачи исходной ошибки клиентскому приложению, чтобы его можно было обрабатывать там.

Ниже приведен пример повтора ошибки.

BEGIN TRY
    -- code to be executed
END TRY
BEGIN CATCH
    PRINT ERROR_MESSAGE();
    THROW
END CATCH

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

Что такое функции обработки ошибок

Блоки CATCH предоставляют сведения, связанные с ошибками, на протяжении всей длительности блока CATCH. К ним относятся подобласти, такие как хранимые процедуры, которые выполняются из блока CATCH.

Функции обработки ошибок

Следует помнить, что при использовании @@ERROR в программировании значение системной переменной @@ERROR сбрасывается, как только выполняется следующая инструкция.

Еще одним ключевым преимуществом структурированной обработки исключений в T-SQL является предоставление ряда функций обработки ошибок и сохранение их значений в блоке CATCH. Отдельные функции предоставляют каждое свойство возникной ошибки.

Это означает, что можно написать универсальные хранимые процедуры обработки ошибок, которые по-прежнему могут получить доступ к сведениям, связанным с ошибками.

  • Блоки CATCH предоставляют сведения, связанные с ошибками, на протяжении всей длительности блока CATCH.
  • @@Error сбрасывается при выполнении следующей инструкции.

Управление ошибками в коде

Интеграция CLR в SQL позволяет выполнять управляемый код в SQL Server. Высокоуровневые языки .NET, такие как C# и VB, имеют подробную обработку исключений, доступную для них. Ошибки можно поймать с помощью стандартных блоков .NET try/catch/finally.

Ошибки в управляемом коде

В общем случае, вам стоит по возможности ловить ошибки в управляемом коде. Однако важно понимать, что все ошибки, не обрабатываемые в управляемом коде, передаются обратно в вызывающий код T-SQL. Каждый раз, когда ошибка в управляемом коде возвращается в SQL Server, она будет ошибкой 6522. Ошибки могут быть вложены, и эта конкретная ошибка может скрывать истинную причину.

Еще одна редкая, но возможная причина ошибок в управляемом коде — это то, что код может выполнять инструкцию RAISERROR T-SQL через объект SqlCommand.