如何防止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.
以下 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.