可以将nvl()函数级联,...在IBM采访中有人问我.....为什么????
答案 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要求所有参数都具有相同的数据类型,因此
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
(因为“某些文字”对日期的隐式转换尝试失败了)