在一个存储过程(它的日期参数名为’paramDate’)中,我有一个类似这样的查询
select id, name from customer where period_aded = to_char(paramDate,'mm/yyyy')
Oracle将每一行的paramDate转换为字符串吗?
我确定Oracle不会,但是有人告诉我Oracle会。实际上,我认为如果函数的参数是约束条件(查询中没有固定值或计算值),结果应该始终相同,这就是Oracle应该只执行一次此转换的原因。然后我意识到有时我会在多个函数中执行DML语句,这可能会导致结果值发生变化,即使每行的值都没有变化。
这应该意味着我应该在将这些值添加到查询之前进行转换。
无论如何,也许一次(内置)众所周知的“已知函数”都会被评估一次,甚至我的函数也会被评估一次。
反正…
oracle将执行一次to_char还是Oracle将对每一行执行一次?
谢谢你的回答
我认为通常不是这种情况,因为它会阻止使用索引。
至少对于内置功能,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')))
有关用户定义的功能,请查看本文。它提到了两种确保函数仅被调用一次的方法:
从Oracle 10.2开始,您可以将函数定义为DETERMINISTIC。
在较旧的版本上,您可以重新命名为使用“标量子查询缓存”:
从雇员薪水中选择COUNT(*)=(从DUAL中选择getValue(1));