我试图理解这个函数:
NVL2( NULL, ( SYSDATE - SYSDATE ), DATE '2020-05-24' ))
Run Code Online (Sandbox Code Playgroud)
以及它的返回值:
NVL2(NULL,(SYSDATE-SYSDATE),DATE '2020-05-24'))
2458994
Run Code Online (Sandbox Code Playgroud)
我无法理解那个数字 ,2458994来自哪里,就像SYSDATE-SYSDATEa 一样NUMBER,你不能隐式地将 a 转换DATE为 a NUMBER:
TO_NUMBER(DATE '2020-05-24')
ORA-01722: invalid number
Run Code Online (Sandbox Code Playgroud)
如果 expr2 是数字数据,则 Oracle 数据库确定哪个参数具有最高的数字优先级,将另一个参数隐式转换为该数据类型,并返回该数据类型。
所以我的问题是,ORACLE SQL 在DATE数据类型上使用什么形式的转换来使其成为NUMBER数据类型?
它有效地做:
to_number(to_char(DATE '2020-05-24','J'))
Run Code Online (Sandbox Code Playgroud)
'J' 是(来自文档):
儒略日;自公元前 4712 年 1 月 1 日以来的天数。J 指定的数字必须是整数。
如果您手动运行它,它会获得与您看到的相同的值:
select to_number(to_char(DATE '2020-05-24','J')) from dual;
2458994
Run Code Online (Sandbox Code Playgroud)
不明显它应该这样做,但确实如此。如果第二个参数是一个普通的(type-2)数字,那么你会得到一个错误:
select NVL2(NULL,42,to_date('2020-05-24','YYYY-MM-DD')) from dual;
ORA-00932: inconsistent datatypes: expected NUMBER got DATE
Run Code Online (Sandbox Code Playgroud)
如果您转储日期减法结果,它会以不同的(内部的,据我所知未记录)数据类型返回:
select dump(SYSDATE-SYSDATE) from dual;
Typ=14 Len=8: 114,133,37,0,0,0,0,0
Run Code Online (Sandbox Code Playgroud)
这似乎导致第三个参数被转换为相同的类型;它几乎相当于:
select DATE '2020-05-24' - DATE '-4712-01-01' from dual;
2458993
Run Code Online (Sandbox Code Playgroud)
所以看起来它要么在做类似的事情但调整它,要么做'J'转换的内部版本,或者......其他一些模糊的相似。它似乎不是记录在案的行为。