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

Определение описания блока обработки исключений.

           
< блок обработки исключений >::=
EXCEPTIONS
WHEN имя исключения[, …] THEN
[< операторы > | IGNORE]
[WHEN имя исключения[, …] THEN
[< операторы > | IGNORE]]
… [WHEN OTHERS THEN
[< операторы > | IGNORE]]
[WHEN ALL THEN
[< операторы > | IGNORE]]

Синтаксические правила

  1. < Имя исключения >[, …] – это одно или более определенных в блоке описаний имен, разделенных запятыми.

  2. При возникновении исключения переменной, при обработке которой возникло это исключение, присваивается NULL-значение.

  3. Фраза WHEN < список имен исключений > THEN < операторы > задает обработку конкретных декларированных в блоке описаний исключений. Исключения можно группировать в отдельные подгруппы в зависимости от алгоритма их обработки.

  4. Фраза WHEN OTHERS THEN < операторы > задает обработку всех декларированных в блоке описаний исключений, обработка которых не предусмотрена в предыдущих фразах WHEN….

  5. Фраза WHEN ALL THEN < операторы > гарантирует обработку всех возникших в процедуре исключений. Она относится ко всем не обрабатываемым в предыдущих фразах WHEN… исключениям (как декларированным в блоке описаний, так и не декларированным).

  6. Оператор IGNORE заставляет процедуру игнорировать перечисленные критичные исключения. Критичными считаются исключения: DIVZERO, UNDEFPROC, BADPARAM, BADRETVAL, BADCURSOR, CURNOTOPEN, OVERFLOW. Некритичные исключения игнорируются по умолчанию.

    Когда в процедуре происходит указанное исключение, управление передается на соответствующие операторы после WHEN, которые выполняются до следующего WHEN, после чего происходит возврат из процедуры (аналогично оператору RETURN). Выполнение процедуры может быть продолжено с помощью оператора GOTO.

  7. Если конструкции WHEN, WHEN OTHERS и WHEN ALL не заданы, то исключения, для которых не задан код обработки, но которые определены в блоке описаний, автоматически передаются на верхний уровень (RESIGNAL). Все неопределенные в блоке описаний исключения, кроме критичных для исполнения, игнорируются. Критичными считаются следующие исключения: DIVZERO, UNDEFPROC, BADPARAM, BADRETVAL, BADCURSOR, CURNOTOPEN, OVERFLOW. Если происходит такое исключение, и для него нет обработчика, автоматически выполняется RESIGNAL.

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

exceptions
  when notab then
    close first_cursor;
    goto notab_recovery;
  when badcur then
    success := false;
  when others then
    success := false;
    resignal;

Пример использования фразы WHEN ALL…

create or replace procedure "te"(in i int) result int for debug
declare
  exception e1 for custom 1;
  exception e2 for custom 2;
code
  if i <  0 then
    signal e1;
  elseif i  > 10 then
    signal e2;
  endif
  execute direct "select * from qwert;";
  return 0;
exceptions
  when e1 then
    return 1;
  when others then
    return 2;
  when all then
    return -1;
end;

Примеры использования фразы IGNORE

1)
create or replace procedure TEST (in i int) result int
declare
  exception DIVZERO for DIVZERO;
  var j int;
code
  j:=10/0;
  return 1;
exceptions 
  when DIVZERO then 
    ignore;
end;

execute TEST(1);
Результат выполнения:
return value = 1

2)
create or replace procedure TEST (in i int) result int
declare
  exception DIVZERO for DIVZERO;
  exception CURNOTOPEN for CURNOTOPEN;
  var j int;
  var c cursor(i int);
code
  close c;
  j:=10;
  return j;
exceptions 
  when DIVZERO 
    then resignal; 
  when others 
    then ignore;
end;

3)
create or replace procedure TEST (in i int) result int
declare
  exception CURNOTOPEN for CURNOTOPEN;
  exception DIVZERO for DIVZERO;
  var j int;
  var c cursor(i int);
code
  close c;
  j:=10;
  return j;
exceptions 
  when all then ignore;
end;

4)
create or replace procedure TEST (in i int) result int
declare
  var j int;
  var c cursor(i int);
code
  close c;
  j:=10;
  return j;
exceptions 
  when all then ignore;
end;

5)
create or replace procedure TEST (in i int) result int
declare
  exception DIVZERO for DIVZERO;
  exception CURNOTOPEN for CURNOTOPEN;
  var j int;
  var c cursor(i int);
code
  close c;
  j:=10;
  return j;
exceptions 
  when DIVZERO, CURNOTOPEN then ignore; //
end;