Обработка исключений в Oracle PL/SQL (примеры)
Что такое обработка исключений в PL/SQL?
Исключение возникает, когда механизм PL/SQL встречает инструкцию, которую он не может выполнить из-за ошибки, возникающей во время выполнения. Эти ошибки не будут зафиксированы во время компиляции, и, следовательно, их необходимо обрабатывать только во время выполнения.
Например, если механизм PL/SQL получает команду разделить любое число на «0», то механизм 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.
- Предопределенные исключения
- Пользовательское исключение
Предопределенные исключения
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» |
Пользовательское исключение
In 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 используется в программе отдельно, то уже возникшее исключение будет распространено на родительский блок. Можно использовать только в блоке исключений, как показано ниже.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> EXCEPTION WHEN <exception_name> THEN <Handler> RAISE; END;
Объяснение синтаксиса:
- В приведенном выше синтаксисе ключевое слово RAISE используется в блоке обработки исключений.
- Всякий раз, когда программа встречает исключение «имя_исключения», исключение обрабатывается и завершается нормально.
- Но ключевое слово RAISE в части обработки исключений распространит это конкретное исключение на родительскую программу.
Примечание: При возникновении исключения в родительском блоке возникающее исключение также должно быть видимым в родительском блоке, иначе oracle выдаст ошибку.
- Мы можем использовать ключевое слово RAISE, за которым следует имя исключения, чтобы вызвать это конкретное пользовательское/предопределенное исключение. Это можно использовать как в части выполнения, так и в части обработки исключений, чтобы вызвать исключение.
CREATE [ PROCEDURE | FUNCTION ] AS BEGIN <Execution block> RAISE <exception_name> EXCEPTION WHEN <exception_name> THEN <Handler> END;
Объяснение синтаксиса:
- В приведенном выше синтаксисе ключевое слово RAISE используется в части выполнения, за которым следует исключение «имя_исключения».
- Это вызовет это конкретное исключение во время выполнения, и его необходимо обработать или вызвать дальше.
Пример 1: В этом примере мы увидим
- Как объявить исключение
- Как вызвать объявленное исключение и
- Как распространить его на основной блок
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 и иметь префикс «-».
Итого
После этой главы. вы должны быть в состоянии работать в следующих аспектах Pl SQL Исключения
- Обработка исключений
- Определить исключение
- Поднять исключение
- Распространение исключений