在存储过程(有一个名为 'paramDate' 的日期参数)中,我有一个像这样的查询
select id, name
from customer
where period_aded = to_char(paramDate,'mm/yyyy')
Oracle会将每行的paramDate转换为字符串吗?
我确信 Oracle 不会,但有人告诉我 Oracle 会。
事实上,我认为如果函数的参数是约束(在查询中没有得到字段或计算值),结果应该总是相同的,这就是为什么 Oracle 应该只执行一次这种转换。
然后我意识到我有时会在多个函数中执行 DML 语句,这可能会导致结果值发生变化,即使它不会针对每一行发生变化。
这应该意味着我应该在将这些值添加到查询之前对其进行转换。
无论如何,也许众所周知的“已知函数”(内置)会被评估一次,甚至我的函数也会被评估一次。
无论如何,再一次...
Oracle 会执行一次 to_char 还是会为每一行执行一次?
感谢您的回答
我认为通常情况并非如此,因为它会阻止使用索引。
至少对于内置函数,Oracle 应该能够弄清楚它只能对其进行一次评估。 (对于用户定义的函数,请参见下文)。
这是使用索引的情况(并且不会对每一行评估该函数):
SQL> select id from tbl_table where id > to_char(sysdate, 'YYYY');
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 35 | 140 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| SYS_C004274 | 35 | 140 | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("ID">TO_NUMBER(TO_CHAR(SYSDATE@!,'YYYY')))
对于用户定义的函数,请查看此article http://www.inside-oracle-apex.com/caution-when-using-plsql-functions-in-sql-statement/。它提到了两种方法来确保
你的函数只被调用一次:
从 Oracle 10.2 开始,您可以将函数定义为 DETERMINISTIC。
-
在旧版本上,您可以将其重新表述为使用“标量子查询缓存”:
选择计数(*)
来自员工
WHERE SALARY = (从 DUAL 中选择 getValue(1));
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)