8

有谁知道,为什么 Oracle 的NVL(and 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

4 回答 4

8

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

改为使用COALESCE以获得短路行为。

于 2010-01-08T10:29:31.383 回答
5

这是一个帖子,Tom Kyte 证实了这一点decodecase短路但没有nvl,但他没有给出理由或文件说明原因。只是说它是:

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

因此,在您的情况下,您应该使用decodeorcase而不是nvl在查询中调用昂贵的函数。

于 2010-01-07T15:59:09.610 回答
3

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

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

于 2010-01-07T15:13:29.860 回答
0

它们显然不是短路的,但我在 Oracle 文档中找不到任何参考资料。

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

于 2010-01-07T15:13:11.357 回答