Обработка исключений в Oracle PL/SQL (примеры)

Что такое обработка исключений в PL/SQL?

Исключение возникает, когда механизм PL/SQL встречает инструкцию, которую он не может выполнить из-за ошибки, возникающей во время выполнения. Эти ошибки не будут зафиксированы во время компиляции, и, следовательно, их необходимо обрабатывать только во время выполнения.

Например, если механизм PL/SQL получает команду разделить любое число на «0», то механизм PL/SQL выдаст это как исключение. Исключение генерируется только во время выполнения механизмом PL/SQL.

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

Синтаксис обработки исключений

Исключения обрабатываются на уровне блока, т. е. если в каком-либо блоке возникает какое-либо исключение, то управление выходит из исполнительной части этого блока. Затем исключение будет обработано в части обработки исключений этого блока. После обработки исключения невозможно повторно отправить управление обратно в раздел выполнения этого блока.

Приведенный ниже синтаксис объясняет, как перехватить и обработать исключение.

Обработка исключений в PL/SQL

BEGIN
<execution block>
.
.
EXCEPTION
WHEN <exceptionl_name>
THEN
  <Exception handling code for the “exception 1 _name’' >
WHEN OTHERS
THEN
  <Default exception handling code for all exceptions >
END;

Объяснение синтаксиса:

  • В приведенном выше синтаксисе блок обработки исключений содержит ряд условий WHEN для обработки исключения.
  • За каждым условием WHEN следует имя исключения, которое, как ожидается, будет вызвано во время выполнения.
  • Когда во время выполнения возникает какое-либо исключение, механизм PL/SQL будет искать это конкретное исключение в части обработки исключений. Он начнется с первого предложения «WHEN» и будет последовательно искать.
  • Если он нашел обработку исключения для возникшего исключения, то он выполнит эту конкретную часть кода обработки.
  • Если ни одно из предложений «WHEN» не присутствует для возникшего исключения, то механизм PL/SQL выполнит часть «WHEN OTHERS» (если она присутствует). Это общее для всех исключение.
  • После выполнения исключения управление деталью выйдет из текущего блока.
  • Для блока во время выполнения может быть выполнена только одна часть исключения. После его выполнения контроллер пропустит оставшуюся часть обработки исключений и выйдет из текущего блока.

Примечание: WHEN OTHERS всегда должен находиться в последней позиции последовательности. Часть обработки исключений, присутствующая после WHEN OTHERS, никогда не будет выполнена, поскольку элемент управления выйдет из блока после выполнения WHEN OTHERS.

Типы исключений

Существует два типа исключений в ПЛ/SQL.

  1. Предопределенные исключения
  2. Пользовательское исключение

Предопределенные исключения

Oracle предопределил некоторые распространенные исключения. Эти исключения имеют уникальное имя исключения и номер ошибки. Эти исключения уже определены в пакете STANDARD в Oracle. В коде мы можем напрямую использовать эти предопределенные имена исключений для их обработки.

Ниже приведены несколько предопределенных исключений.

Исключение Код ошибки Причина исключения
ACCESS_INTO_NULL ORA-06530 Присвойте значение атрибутам неинициализированных объектов
CASE_NOT_FOUND ORA-06592 Ни одно из предложений WHEN в операторе CASE не удовлетворено, и предложение ELSE не указано.
COLLECTION_IS_NULL ORA-06531 Использование методов коллекции (кроме EXISTS) или доступ к атрибутам коллекции в неинициализированной коллекции.
CURSOR_ALREADY_OPEN ORA-06511 Пытаюсь открыть курсор который уже открыт
DUP_VAL_ON_INDEX ORA-00001 Сохранение повторяющегося значения в столбце базы данных, который является ограниченным уникальным индексом.
INVALID_CURSOR ORA-01001 Недопустимые операции с курсором, например закрытие неоткрытого курсора.
НЕПРАВИЛЬНЫЙ НОМЕР ORA-01722 Преобразование символа в число не удалось из-за недопустимого числового символа.
ДАННЫЕ НЕ НАЙДЕНЫ ORA-01403 Когда оператор SELECT, содержащий предложение INTO, не извлекает строки.
ROW_MISMATCH ORA-06504 Когда тип данных переменной курсора несовместим с фактическим типом возвращаемого значения курсора
SUBSCRIPT_BEYOND_COUNT ORA-06533 Обращение к коллекции по индексному номеру, превышающему размер коллекции.
SUBSCRIPT_OUTSIDE_LIMIT ORA-06532 Обращение к коллекции по индексному номеру, выходящему за пределы допустимого диапазона (например: -1).
TOO_MANY_ROWS ORA-01422 Когда инструкция SELECT с предложением INTO возвращает более одной строки
VALUE_ERROR ORA-06502 Арифметическая ошибка или ошибка ограничения размера (например: присвоение значения переменной, превышающей размер переменной)
ZERO_DIVIDE ORA-01476 Деление числа на «0»

Пользовательское исключение

В Oracle, помимо заранее определенных исключений, программист может создавать свои собственные исключения и обрабатывать их. Их можно создать на уровне подпрограммы в части объявлений. Эти исключения видны только в этой подпрограмме. Исключение, определенное в спецификации пакета, является общедоступным и видно везде, где пакет доступен.

Синтаксис: На уровне подпрограммы

DECLARE
<exception_name> EXCEPTION; 
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
<Handler>
END;
  • В приведенном выше синтаксисе переменная «имя_исключения» определена как тип «ИСКЛЮЧЕНИЕ».
  • Это можно использовать аналогично предопределенному исключению.

Синтаксис:На уровне спецификации пакета

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • В приведенном выше синтаксисе переменная «имя_исключения» определена как тип «ИСКЛЮЧЕНИЕ» в спецификации пакета. .
  • Это можно использовать в базе данных везде, где может быть вызван пакет package_name.

PL/SQL вызывает исключение

Все предопределенные исключения вызываются неявно при возникновении ошибки. Но определяемые пользователем исключения необходимо вызывать явно. Этого можно добиться, используя ключевое слово «RAISE». Это можно использовать любым из способов, упомянутых ниже.

Если RAISE используется в программе отдельно, то уже возникшее исключение будет распространено на родительский блок. Можно использовать только в блоке исключений, как показано ниже.

PL/SQL вызывает исключение

CREATE [ PROCEDURE | FUNCTION ]
 AS
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
             <Handler>
RAISE;
END;

Объяснение синтаксиса:

  • В приведенном выше синтаксисе ключевое слово RAISE используется в блоке обработки исключений.
  • Всякий раз, когда программа встречает исключение «имя_исключения», исключение обрабатывается и завершается нормально.
  • Но ключевое слово RAISE в части обработки исключений распространит это конкретное исключение на родительскую программу.

Примечание: При возникновении исключения в родительском блоке возникающее исключение также должно быть видимым в родительском блоке, иначе oracle выдаст ошибку.

  • Мы можем использовать ключевое слово RAISE, за которым следует имя исключения, чтобы вызвать это конкретное пользовательское/предопределенное исключение. Это можно использовать как в части выполнения, так и в части обработки исключений, чтобы вызвать исключение.

PL/SQL вызывает исключение

CREATE [ PROCEDURE | FUNCTION ] 
AS
BEGIN
<Execution block>
RAISE <exception_name>
EXCEPTION
WHEN <exception_name> THEN
<Handler>
END;

Объяснение синтаксиса:

  • В приведенном выше синтаксисе ключевое слово RAISE используется в части выполнения, за которым следует исключение «имя_исключения».
  • Это вызовет это конкретное исключение во время выполнения, и его необходимо обработать или вызвать дальше.

Пример 1: В этом примере мы увидим

  • Как объявить исключение
  • Как вызвать объявленное исключение и
  • Как распространить его на основной блок

PL/SQL вызывает исключение

PL/SQL вызывает исключение

DECLARE
Sample_exception EXCEPTION;
PROCEDURE nested_block
IS
BEGIN
Dbms_output.put_line(‘Inside nested block’);
Dbms_output.put_line(‘Raising sample_exception from nested block’);
RAISE sample_exception;
EXCEPTION
WHEN sample_exception THEN 
Dbms_output.put_line (‘Exception captured in nested block. Raising to main block’);
RAISE,
END;
BEGIN
Dbms_output.put_line(‘Inside main block’);
Dbms_output.put_line(‘Calling nested block’);
Nested_block;
EXCEPTION
WHEN sample_exception THEN	
Dbms_output.put_line (‘Exception captured in main block');
END:
/

Пояснение к коду:

  • Строка кода 2: объявление переменной sample_Exception как типа EXCEPTION.
  • Строка кода 3: Объявление процедурыnested_block.
  • Строка кода 6: Печать оператора «Внутри вложенного блока».
  • Строка кода 7: Печать оператора «Вызов sample_Exception из вложенного блока».
  • Строка кода 8: Вызов исключения с помощью RAISE sample_Exception.
  • Строка кода 10: Обработчик исключений для исключения sample_Exception во вложенном блоке.
  • Строка кода 11: Печать оператора «Исключение, зафиксированное во вложенном блоке. Подъем на главный блок».
  • Строка кода 12: Вызов исключения в основной блок (распространение на главный блок).
  • Строка кода 15: Печать заявления «Внутри основного блока».
  • Строка кода 16: Печать оператора «Вызов вложенного блока».
  • Строка кода 17: Вызов процедурыnested_block.
  • Строка кода 18: Исключение
  • Строка кода 19: Обработчик исключений для sample_Exception в основном блоке.
  • Строка кода 20: Печать оператора «Исключение, зафиксированное в основном блоке».

Важные моменты, на которые следует обратить внимание в исключении

  • В функции исключение всегда должно либо возвращать значение, либо вызывать дальнейшее исключение. иначе Oracle выдаст ошибку «Функция возвращена без значения» во время выполнения.
  • Операторы управления транзакциями могут быть заданы в блоке обработки исключений.
  • SQLERRM и SQLCODE — это встроенные функции, которые выдают сообщение и код исключения.
  • Если исключение не обрабатывается, то по умолчанию все активные транзакции в этом сеансе будут отменены.
  • RAISE_APPLICATION_ERROR (- , ) можно использовать вместо RAISE, чтобы вызвать ошибку с помощью пользовательского кода и сообщения. Код ошибки должен быть больше 20000 и иметь префикс «-».

Итоги

После этой главы. ты должен иметь возможность работать на следующегоwing аспекты Pl SQL Исключения

  • Обработка исключений
  • Определить исключение
  • Поднять исключение
  • Распространение исключений