Oracle PL/SQL求值顺序

Oracle PL/SQL求值顺序,oracle,plsql,Oracle,Plsql,你好。考虑以下事项: SQL> DECLARE 2 b1 BOOLEAN; 3 b2 BOOLEAN; 4 FUNCTION checkit RETURN BOOLEAN IS 5 BEGIN 6 dbms_output.put_line('inside checkit'); 7 RETURN TRUE; 8 END checkit; 9 10 PROCEDURE ou

你好。考虑以下事项:

SQL> DECLARE
  2     b1   BOOLEAN;
  3     b2   BOOLEAN;
  4     FUNCTION checkit RETURN BOOLEAN IS
  5     BEGIN
  6        dbms_output.put_line('inside checkit');
  7        RETURN TRUE;
  8     END checkit;
  9  
 10     PROCEDURE outp(n VARCHAR2, p BOOLEAN) IS
 11     BEGIN
 12        IF p THEN
 13           dbms_output.put_line(n||' is true');
 14        ELSE
 15           dbms_output.put_line(n||' is false');
 16        END IF;
 17     END;
 18  BEGIN
 19     b1 := TRUE OR checkit;
 20     outp('b1',b1);
 21     b2 := checkit OR TRUE;
 22     outp('b2',b2);
 23  END;
 24  /

b1 is true
inside checkit
b2 is true

PL/SQL procedure successfully completed

SQL> 
请注意,OR语句的结果取决于顺序。如果我先调用函数,那么不管其他项的值如何,函数都会执行。似乎OR语句是从左到右求值的,直到获得TRUE,此时处理停止,结果为TRUE

我的问题是,这是我可以依靠的吗?或者这种行为会在未来的PL/SQL版本中发生变化吗?如果可以更改,是否有一种方法可以强制计算我可以依赖的函数(无需创建另一个变量并使用单独的赋值语句)?

是。PL/SQL从左到右执行逻辑表达式的运算。

这称为“短路求值”,它是大多数语言的标准

如果可以更改,是否有一种方法可以强制对函数求值,而我可以依赖它(无需创建另一个变量并使用单独的赋值语句)


如果您要求函数必须求值,即使在逻辑上这样做是多余的,这意味着它执行的操作不是简单地返回TRUE或FALSE,例如,它可能会更新表。PL/SQL函数产生这样的“副作用”被认为是不好的做法

在文档中,它指出短路评估适用于IF、CASE和CASE表达式:我敢打赌它也适用于您引用的示例,但技术上没有文档证明它是这样做的。可能值得向Oracle提出这一行为的问题以得到确认。

它从左到右计算OR语句,从右到左计算and语句。我没有找到任何关于它的文件

你所说的“.和从右到左的陈述”到底是什么意思
这来自oracle文档=>

在以下示例中,请注意,当valid的值为FALSE时,无论done的值是多少,整个表达式都会生成FALSE:

有理有据

您可以在以下示例中检查顺序:

声明
b1布尔型
b2布尔型

功能检查(v编号)
返回布尔值

开始
DBMS_OUTPUT.put_line('内部检查:'| | v)
返回TRUE
结束检查

过程输出(n VARCHAR2,p BOOLEAN)

开始
如果p
然后
DBMS_OUTPUT.put_行(n | |'为真')
否则
DBMS|u OUTPUT.put|u行(n | |'为false')
如果结束
结束
开始
b1:=检查(1)和检查(2)
输出('b1',b1)
b2:=检查(3)和检查(4)
输出('b2',b2)
结束


内部检查:1
内部检查:2
b1为真
内部检查:3
内部检查:4

b2是正确的

完美。这正是我要找的!我在谷歌上搜索“pl/sql完全布尔求值”时,得到了完全相同的链接。这比我尝试的搜索“PLSQL强制求值”要好。谢谢一系列编辑功能。每个问题编辑消息并返回一个指示器,指示是否应跳过当前记录。skip标志开始为FALSE,如果检查失败,则设置为TRUE。如果跳过标志通过任何特定检查,我不希望将其重置为FALSE。您可以通过过程将这些函数替换为标志的IN-OUT参数。如果任何检查失败,程序将把标志设置为TRUE,但如果没有检查失败,则不使用它:l_标志:=FALSE;do_check1(左_标志);do_check2(l_标志);do_check3(左_标志);