为什么NVL总是评估第二个参数

时间:2010-01-07 15:02:58

标签: sql oracle nvl

有谁知道,为什么Oracle的NVL(和NVL2)函数总是评估第二个参数,即使第一个参数不是NULL

简单测试:

CREATE FUNCTION nvl_test RETURN NUMBER AS
BEGIN
  dbms_output.put_line('Called');
  RETURN 1;
END nvl_test;

SELECT NVL( 0, nvl_test ) FROM dual

返回0,但也会打印Called

已调用

nvl_test,即使结果被忽略,因为第一个参数不是NULL

4 个答案:

答案 0 :(得分:8)

一直都是这样,因此Oracle必须保持这种方式以保持向后兼容。

使用COALESCE来获取短路行为。

答案 1 :(得分:5)

以下是Tom Kyte确认decodecase短路而非nvl的帖子,但他没有提供理由或说明原因。请说明:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:926029357278#14932880517348

因此,在您的情况下,如果您的查询中会调用昂贵的函数,则应使用decodecase代替nvl

答案 2 :(得分:3)

通常,在调用函数之前计算第二个参数是有意义的,因为通常调用函数的方式是:计算函数的所有参数,并将计算值发送给函数。

然而,在像NVL这样非常常见的系统功能的情况下,我认为PL / SQL可以优化,将函数调用视为一种特殊情况。但也许这比听起来更困难(对我来说),因为我确信这种优化会发生在Oracle的开发者身上。

答案 3 :(得分:0)

它们显然不是短路的,但我在Oracle文档中找不到任何引用。

查看此讨论:http://forums.oracle.com/forums/thread.jspa?messageID=3478040