首页 > 解决方案 > ORACLE 数据库如何将 DATE 隐式转换为 NUMBER?

问题描述

我试图理解这个功能:

NVL2( NULL, ( SYSDATE - SYSDATE ), DATE '2020-05-24' ))

及其返回值:

NVL2(NULL,(SYSDATE-SYSDATE),DATE '2020-05-24'))

2458994

我无法理解该数字 ,2458994的来源,就像SYSDATE-SYSDATEa一样NUMBER,并且您不能将 a隐式转换DATE为 a NUMBER

TO_NUMBER(DATE '2020-05-24')
ORA-01722: invalid number

ORACLE SQL 语言参考 NVL2指出:

如果 expr2 是数字数据,则 Oracle 数据库确定哪个参数具有最高的数字优先级,将另一个参数隐式转换为该数据类型,并返回该数据类型。

所以我的问题是,ORACLE SQL 在DATE数据类型上使用什么形式的转换来使其成为NUMBER数据类型?

标签: sqloracle

解决方案


它有效地做:

to_number(to_char(DATE '2020-05-24','J'))

'J' 是(来自文档):

朱利安日;自公元前 4712 年 1 月 1 日以来的天数。用 J 指定的数字必须是整数。

如果您手动运行它,它将获得与您看到的相同的值:

select to_number(to_char(DATE '2020-05-24','J')) from dual;

2458994

应该这样做并不明显,但确实如此。如果第二个参数是一个普通的(type-2)数字,那么你会得到一个错误:

select NVL2(NULL,42,to_date('2020-05-24','YYYY-MM-DD')) from dual;

ORA-00932: inconsistent datatypes: expected NUMBER got DATE

如果您转储日期减法结果,它会以不同的(内部,据我所知未记录)数据类型返回:

select dump(SYSDATE-SYSDATE) from dual;

Typ=14 Len=8: 114,133,37,0,0,0,0,0

这似乎导致第三个参数被转换为相同的类型;它几乎等同于:

select DATE '2020-05-24' - DATE '-4712-01-01' from dual;

2458993

所以看起来它要么在做类似的事情,但要对其进行调整,或者做一个内部版本的“J”转换,或者......其他一些模糊相似的事情。它似乎没有记录在案的行为。


推荐阅读