Bri*_*ser 1 sql oracle plsql short-circuiting
要允许超级用户/管理员登录我的系统,我正在运行(更大版本)此查询:
Select *
  From mytable
 Where (:id = 'Admin' Or :id = mytable.id);
如果我传递用户ID,我会获得该用户的所有数据; 如果我传递字符串'Admin',我会得到所有数据.这是有效的,因为Oracle的OR是一个短路运算符.
但是,如果我将'Admin'作为一个包常量并使用函数来获取它,就像这样
Select *
  From mytable
 Where (:id = mypackage.GetAdminConstant Or :id = mytable.id);
ORA-01722: invalid number当我通过'Admin'时,我得到了.
当我引入函数时,为什么OR会失去其短路方面?
它不会失去短路方面.但SQL不是一种过程语言,并且不能保证多个谓词的评估顺序.
在C中,如果您编写a || b,您知道a将首先进行评估,然后b仅在必要时进行评估.
在SQL中,如果你写的a OR b,你只知道,要么a或b将首先评估,以及其他的表达(至少在甲骨文)将只在必要时进行评估.
查看两个查询的执行计划可能会给出评估顺序的一些指示,或者可能没有.
我猜想,在第一种情况下,Oracle可以看到第一个表达式对于每一行都具有相同的值,因此首先对其进行求值.当您更改为第二种情况时,Oracle现在会看到一个函数,每次计算时都会有不同的结果,因此它必须检查每一行,因此它会在执行函数调用之前尝试对列执行简单的相等性检查.
我想知道如果你标记函数DETERMINISTIC你会得到不同的结果,所以Oracle会知道它本质上是一个常数.
| 归档时间: | 
 | 
| 查看次数: | 1828 次 | 
| 最近记录: |