如何防止Oracle在PL/SQL中使用短路

How to prevent Oracle to use short circuit in 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(...) return 为假,以便为每个失败的条件打印 failure_message

问题是 Oracle 使用短路评估并忽略 return false 之后的其余条件。例如,上面的程序打印了下面的信息。

condition 2 failed
some conditions failed, terminate the program

如何告诉 Oracle 不使用短路计算以便上面的程序打印以下消息。

condition 2 failed
condition 3 failed
some conditions failed, terminate the program

尝试:

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;
/

我通常使用 assertions 验证先决条件。我不知道这是否适合 OP 的情况,但我认为它值得一提,作为一种可行的解决方案替代方案。

示例:

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;
/

显然在现实中 code/logic 必须考虑如何处理异常。状态变量也可能是 used/required.