Обработка на изключения в 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' не присъства за изключението, което е било повдигнато, тогава PL/SQL машината ще изпълни частта 'WHEN OTHERS' (ако е налице). Това е общо за всички изключения.
  • След изпълнение на изключението контролът на частта ще излезе извън текущия блок.
  • Само едно изключение може да бъде изпълнено за блок по време на изпълнение. След като го изпълни, контролерът ще пропусне оставащата част за обработка на изключения и ще излезе от текущия блок.

Забележка: WHEN OTHERS винаги трябва да е на последната позиция в последователността. Частта за обработка на изключения, присъстваща след WHEN OTHERS, никога няма да се изпълни, тъй като контролата ще излезе от блока след изпълнение на WHEN OTHERS.

Видове изключения

Има два вида изключения в Pl/SQL.

  1. Предварително дефинирани изключения
  2. Дефинирано от потребителя изключение

Предварително дефинирани изключения

Oracle има предварително определени общи изключения. Тези изключения имат уникално име на изключение и номер на грешка. Тези изключения вече са дефинирани в пакета „СТАНДАРТ“ в 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 Опитвайки се да отворите a курсор който вече е отворен
DUP_VAL_ON_INDEX ORA-00001 Съхраняване на дублирана стойност в колона на база данни, която е ограничена от уникален индекс
INVALID_CURSOR ORA-01001 Незаконни операции с курсора като затваряне на неотворен курсор
INVALID_NUMBER 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 Аритметична грешка или грешка при ограничение на размера (напр.: присвояване на стойност на променлива, която е по-голяма от размера на променливата)
НУЛА_ДЕЛЕНИЕ ORA-01476 Деление на число с '0'

Дефинирано от потребителя изключение

In Oracle, различни от предварително дефинираните по-горе изключения, програмистът може да създаде свои собствени изключения и да ги обработва. Те могат да бъдат създадени на ниво подпрограма в частта за деклариране. Тези изключения са видими само в тази подпрограма. Изключението, което е дефинирано в спецификацията на пакета, е публично изключение и е видимо навсякъде, където пакетът е достъпен.

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

DECLARE
<exception_name> EXCEPTION; 
BEGIN
<Execution block>
EXCEPTION
WHEN <exception_name> THEN 
<Handler>
END;
  • В горния синтаксис променливата 'exception_name' е дефинирана като тип 'EXCEPTION'.
  • Това може да се използва по подобен начин като предварително дефинирано изключение.

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

CREATE PACKAGE <package_name>
 IS
<exception_name> EXCEPTION;
.
.
END <package_name>;
  • В горния синтаксис променливата 'exception_name' е дефинирана като тип 'EXCEPTION' в спецификацията на пакета на .
  • Това може да се използва в базата данни, където може да се извика пакет 'package_name'.

PL/SQL Raise Exception

Всички предварително дефинирани изключения се повдигат имплицитно, когато възникне грешка. Но дефинираните от потребителя изключения трябва да бъдат повдигнати изрично. Това може да се постигне с помощта на ключовата дума „RAISE“. Това може да се използва по всеки от начините, споменати по-долу.

Ако 'RAISE' се използва отделно в програмата, тогава тя ще разпространи вече повдигнатото изключение към родителския блок. Само в блок за изключения може да се използва, както е показано по-долу.

PL/SQL Raise Exception

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

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

  • В горния синтаксис ключовата дума RAISE се използва в блока за обработка на изключения.
  • Всеки път, когато програмата срещне изключение „exception_name“, изключението се обработва и ще бъде завършено нормално
  • Но ключовата дума 'RAISE' в частта за обработка на изключения ще разпространи това конкретно изключение към родителската програма.

Забележка: Докато повдигате изключението към родителския блок, изключението, което се повдига, също трябва да бъде видимо в родителския блок, в противен случай oracle ще изведе грешка.

  • Можем да използваме ключова дума „RAISE“, последвана от името на изключението, за да повдигнем това конкретно дефинирано от потребителя/предефинирано изключение. Това може да се използва както в частта за изпълнение, така и в частта за обработка на изключения за повдигане на изключението.

PL/SQL Raise Exception

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

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

  • В горния синтаксис ключовата дума RAISE се използва в частта за изпълнение, последвана от изключение „exception_name“.
  • Това ще предизвика това конкретно изключение по време на изпълнение и това трябва да бъде обработено или повдигнато допълнително.

Пример 1: В този пример ще видим

  • Как да декларирам изключението
  • Как да повдигнем декларираното изключение и
  • Как да го разпространя в основния блок

PL/SQL Raise Exception

PL/SQL Raise Exception

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 и с префикс „-“.

Oбобщение

След тази глава. трябва да можете да работите за следните аспекти на Pl SQL изключения

  • Обработка на изключенията
  • Дефинирайте изключение
  • Повишете изключението
  • Размножаване на изключение