Формат блока кода
Определение описания блока кода процедурного языка.
::=
::=
Синтаксические правила
-
Представления тела процедуры в виде иерархии вложенных блоков возникает при необходимости локализации обработки исключений, например, исключение 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