Как помешать Oracle использовать короткое замыкание в PL/SQL
Следующий код PL/SQL показывает функцию ensure(...)
и как я буду использовать его в Oracle 11g.
declare
valid boolean;
function ensure(b boolean, failure_message varchar) return boolean is begin
if not b then
dbms_output.put_line(failure_message);
return false;
else
return true;
end if;
end ensure;
begin
valid := true;
valid := valid
and ensure(1=1, 'condition 1 failed')
and ensure(1=2, 'condition 2 failed')
and ensure(2=3, 'condition 3 failed');
if not valid then
dbms_output.put_line('some conditions failed, terminate the program');
return;
end if;
dbms_output.put_line('do the work');
end;
/
Я хочу использовать ensure(...)
Для предварительной проверки набора условий программе разрешено выполнять работу, только если выполнены все условия.
Я хочу, чтобы программа оценивала каждый ensure(...)
даже если предыдущий ensure(...)
вернуть ложь, так что failure_message
будет напечатан для всех условий, которые не удается.
Проблема в том, что Oracle использует оценку короткого замыкания и игнорирует остальные условия, которые следуют за тем, которое возвращает false. Например, вышеприведенная программа печатает следующее сообщение.
condition 2 failed
some conditions failed, terminate the program
Как сказать Oracle не использовать оценку короткого замыкания, чтобы вышеприведенная программа напечатала следующее сообщение.
condition 2 failed
condition 3 failed
some conditions failed, terminate the program
2 ответа
Пытаться:
declare
valid boolean;
con1 boolean;
con2 boolean;
con3 boolean;
function ensure(b boolean, failure_message varchar) return boolean is begin
if not b then
dbms_output.put_line(failure_message);
return false;
else
return true;
end if;
end ensure;
begin
valid := true;
con1 := ensure(1=1, 'condition 1 failed') ;
con2 := ensure(1=2, 'condition 2 failed') ;
con3 := ensure(2=3, 'condition 3 failed');
valid := con1 AND con2 AND con3;
if not valid then
dbms_output.put_line('some conditions failed, terminate the program');
return;
end if;
dbms_output.put_line('do the work');
end;
/
Я обычно проверяю предварительные условия утверждениями. Я не знаю, подходит ли это в случае ОП, но я думаю, что стоит упомянуть в качестве альтернативы жизнеспособного решения.
Пример:
declare
procedure assert(p_cond in boolean, p_details in varchar2 default null) is
begin
if not p_cond then
raise_application_error(-20100, p_details);
end if;
end;
begin
assert(1 = 1, 'first');
assert(1 = 2, 'second');
assert(1 = 1, 'third');
-- all preconditions are valid, processing is "safe"
end;
/
Очевидно, что в реальном коде / логике нужно учитывать, как должны обрабатываться исключения. Также могут быть использованы / обязательны переменные состояния.