参考:https ://docs.oracle.com/cd/B19306_01/server.102/b14200/functions106.htm
第二个参数应该是字符或数字。第二个参数给出了第三个参数将被隐式转换的数据类型。所以:
1. 第一个
SELECT inv_no,NVL2(inv_amt,inv_date,'Not Available') FROM invoice;
不正确,因为您不能将 DATE 作为第二个参数。
一样的方法:
SELECT NVL2(NULLIF(1, 1), SYSDATE, 'A') FROM DUAL; -- FAILS;
SELECT NVL2(NULLIF(1, 0), SYSDATE, 'A') FROM DUAL; -- FAILS;
SELECT NVL2(NULLIF(1, 1), 'A', SYSDATE) FROM DUAL; -- PASS; returns SYSDATE (as char datatype)
SELECT NVL2(NULLIF(1, 0), 'A', SYSDATE) FROM DUAL; -- PASS; returns 'A';
2. 第二个也是无效的:
SELECT inv_no,NVL2(inv_amt,inv_amt*.25,'Not Available') FROM invoice;
Oracle 尝试将第三个参数隐式转换为第二个参数的数据类型,这意味着它尝试将“不可用”转换为数值。
当您交换第二个和第三个参数时,它将起作用:
SELECT inv_no,NVL2(inv_amt,'Not Available',inv_amt*.25) FROM invoice;
inv_amt*.25 将隐式转换为字符数据;这个例子是无用的,因为它会让你 NULL*.25 使它成为 NULL。
但是,您可以做的是,您可以通过将数字结果转换为字符来将两个参数都设为字符:
SELECT inv_no,NVL2(inv_amt,TO_CHAR(inv_amt*.25), 'Not Available') FROM invoice;
尤其是当您想显示货币时,这会很有意义。
3.第三个比较复杂
我能解释的唯一方法是在处理第三个参数之前将第二个参数转换为字符。这样第三个也将转换为字符。考虑到这两种情况,这是有道理的:
SELECT NVL2(2, SYSDATE - TO_DATE('10-JAN-83'), SYSDATE) from dual; -- PASSES
SELECT NVL2(2, 2.2, SYSDATE) from dual; -- FAILS.
最后:我建议坚持 Oracle 的文档并使用显式转换。