Реализация структурированной обработки исключений
Теперь, когда у вас есть представление о характере ошибок и базовой обработке ошибок в 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.