NVL功能可以级联吗?

时间:2009-07-10 11:04:29

标签: sql database oracle plsql

可以将nvl()函数级联,...在IBM采访中有人问我.....为什么????

5 个答案:

答案 0 :(得分:14)

更好的是,使用COALESCE

答案 1 :(得分:8)

我的回答:

  

是的,NVL可以级联。这是我期望在从Oracle版本移植到8i的代码中看到的东西,因为在Oracle 9i之前不支持COALESCE。

     

COALESCE是ANSI SQL 99标准,其作用类似于CASE / SWITCH语句,它如何按顺序计算每个表达式,并且一旦遇到非空表达式,就不会继续计算表达式。这称为短路。使用COALESCE的另一个好处是数据类型不需要匹配,这在使用NVL时是必需的。

此:

SELECT COALESCE( 1.5 / NULL, 
                 SUM(NULL), 
                 TO_CHAR(SYSDATE, 'YYYY') ) abc
  FROM DUAL

...将返回:2009(接下来的~32天,无论如何)

答案 2 :(得分:3)

为什么不呢?例如:

select NVL( null, NVL( null, 1 )) from dual 

可能是这样的:

select NVL( delete_date, NVL( edit_date, create_date ))  AS last_change
from Table

可能是他们想让你说它是确定性的功能。所以它是可以重入的。

答案 3 :(得分:1)

我看到级联NVL的最常见原因是数据库随时间而变化。 原始设计有一个表,后来被更改为在表中有更多列。 Alter语句创建了新的列,允许使用NULL,这被利用了视图,以便 顶部的代码不需要改变。问题是单个列,change_date, 被多列替换。 Update_Date,Comment_Date和Approval_date。每一个 现在将3个新列组合在一起,在视图中使用

获取“change_date”
create or replace view OldTableNmae as
select other_columns
    , nvl ( update_date, nvl ( comment_date, approval_date ) ) change_date
    , more_columns
from  new_table
/

答案 4 :(得分:1)

正如其他人所说,NVL可以级联,但首选的解决方案是使用COALESCE。但是,这两个功能并不完全可以互换:

1)如其他地方所述,COALESCE仅评估第一个参数,直到它满足不评估为null的参数

2)但是,COALESCE要求所有参数都具有相同的数据类型,因此 STRICTER 比NVL首先尝试隐式转换。

E.g。

SELECT COALESCE( 1.5 / NULL, 
             SUM(NULL), 
             TO_CHAR(SYSDATE, 'YYYY') ) abc
FROM DUAL

实际上引发了错误ORA-00932: inconsistent datatypes: expected NUMBER got CHAR

NVL将返回当前年份

SELECT NVL( 1.5 / NULL, 
             NVL( SUM(NULL), 
                 TO_CHAR(SYSDATE, 'YYYY') ) ) abc
FROM DUAL

其他例子:

select coalesce('some text',sysdate) from dual;

投掷ORA-00932: inconsistent datatypes: expected CHAR got DATE,而

select nvl('some text',sysdate) from dual;

返回some text,但

select nvl(sysdate,'some text') from dual;

抛出ORA-01841: (full) year must be between -4713 and +9999, and not be 0(因为“某些文字”对日期的隐式转换尝试失败了)