Как помешать 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;
/

Очевидно, что в реальном коде / логике нужно учитывать, как должны обрабатываться исключения. Также могут быть использованы / обязательны переменные состояния.

Другие вопросы по тегам