Формат блока кода
Определение описания блока кода процедурного языка.
::=::=Синтаксические правила
-
Представления тела процедуры в виде иерархии вложенных блоков возникает при необходимости локализации обработки исключений, например, исключение NULLDATA может генерироваться в каждом вложенном блоке и в каждом из них должно обрабатываться по собственному правилу.
-
Если вложенный блок содержит
<блок обработки исключений>, или блок обработки содержит операторRESIGNAL, то возникшие в этом вложенном блоке исключения обрабатываются сначала в его<блоке обработки исключений>. Если вложенный блок не содержит<блок обработки исключений>или исключение не может быть обработано в его<блоке обработки исключений>, то при запуске ядра СУБД ЛИНТЕР с ключом /COMPATIBILITY=RESIGNAL_ALL исключение передается по иерархии на следующие вложенные блоки (т.е. при таком запуске ядра СУБД нет необходимости в каждом вложенном блоке явно выполнять оператор RESIGNAL), в противном случае обработка исключения сразу передается на<блок обработки исключений>самого верхнего уровня (если этот<блок обработки исключений>задан). -
На любом уровне вложенности при отсутствии ключа /COMPATIBILITY=RESIGNAL_ALL все неопределенные в блоке описаний исключения, кроме критичных для исполнения, игнорируются. Критичными считаются следующие исключения: DIVZERO, UNDEFPROC, BADPARAM, BADRETVAL, BADCURSOR, CURNOTOPEN, NOMEM, OVERFLOW. Если происходит такое исключение, и для него нет обработчика, автоматически выполняется завершение процедуры с передачей исключений выше, в блок вызвавшей процедуры, из которого произошел вызов (с NULL-значением в качестве возвращаемого значения) (см. также оператор RESIGNAL).
-
Исключения, не относящиеся к списку критичных (DIVZERO, UNDEFPROC, BADPARAM, BADRETVAL, BADCURSOR, CURNOTOPEN, OVERFLOW), например, NULLDATA, при отсутствии ключа /COMPATIBILITY=RESIGNAL_ALL, возникшие в блоке CODE...END, не попадут в обработчик предыдущего уровня.
Например, процедура
CREATE OR REPLACE PROCEDURE TST_CODE() RESULT INT FOR DEBUG DECLARE VAR v, z int; EXCEPTION NULLDATA for NULLDATA; CODE v:=3; CODE z:= NULL; v:= z + v; END RETURN 0; EXCEPTIONS WHEN NULLDATA THEN RETURN 1; END; CALL tst_code(); result=1вернёт результат 1, т.к. во вложенном блоке CODE… END нет своего обработчика исключений, и сгенерированное в нем исключение будет передано на обработку на предшествующий по иерархии уровень.
А процедура:
CREATE OR REPLACE PROCEDURE tst_code() RESULT INT FOR DEBUG DECLARE VAR v, z INT; EXCEPTION NULLDATA FOR NULLDATA; CODE v:=3; CODE z:= NULL; v:= z + v; EXCEPTIONS WHEN NULLDATA THEN RETURN 0; END EXCEPTIONS WHEN NULLDATA THEN RETURN 1; END; CALL tst_code(); result=0вернёт результат 0, т.к. во вложенном блоке CODE… END есть свой обработчика исключений, поэтому сгенерированное в нем исключение не будет передано на обработку на предшествующий по иерархии уровень.
Примеры
1)
create or replace procedure tst_code() result int for debug
declare
var make char(20);
exception no_data_found for 2;
exception notab for 2202;
var val_ret int;
-- code1 - первый вложенный блок
code
code
execute "select distinct model from auto where make like 'F%'and personid=90;" into make;
exceptions
when no_data_found then
val_ret:=-1;
goto ret;
when notab then
val_ret:=-2;
goto ret;
end
-- code2 - второй вложенный блок
code
execute "select distinct model from auto where make like 'F%'and personid=-1" into make;
exceptions
when no_data_found then
val_ret:=-3;
goto ret;
when notab then
val_ret:=-4;
goto ret;
end
ret: return val_ret;
end;
call tst_code();
result -3
2)
create or replace procedure tst_code() result int for debug
declare
var make char(20);
exception no_data_found for 2;
exception notab for 2202;
var val_ret int;
// code1 - первый вложенный блок
code
val_ret:=100;
code
execute "select distinct model from auto where make like 'F%'and personid=-1;" into make;
code
execute "select distinct model from auto where make like 'F%'and personid=90;" into make;
exceptions
when no_data_found then
val_ret:=-3;
goto ret;
when notab then
val_ret:=-4;
goto ret;
end
exceptions
when no_data_found then
val_ret:=-1;
goto ret;
when notab then
val_ret:=-2;
goto ret;
end
ret: return val_ret;
end;
call tst_code();
result -1