sql oracle todate差异

bob*_*lan 0 sql oracle date

有人可以向我解释当查询1返回查询2中使用的替换值时,为什么查询4的输出与其他输出不同,这应该等同于运行与查询4相同的操作?

我怀疑它与nls_date_format有关,但我不确定.

查询1

SELECT TO_DATE(SYSDATE, 'DD/MON/YYYY')FROM DUAL;
TO_DATE(SYSDATE,'DD/MON/YYYY')
------------------------------
02-SEP-15 
Run Code Online (Sandbox Code Playgroud)

查询2

SELECT TO_DATE('02-SEP-15') - TO_DATE('01/JAN/07') FROM DUAL;
TO_DATE('02-SEP-15')-TO_DATE('01/JAN/07')
-----------------------------------------
                                     3166

SELECT TO_DATE(SYSDATE, 'DD/MON/YY') - TO_DATE('01/JAN/2007') FROM DUAL;
Run Code Online (Sandbox Code Playgroud)

查询3

TO_DATE(SYSDATE,'DD/MON/YY')-TO_DATE('01/JAN/2007')
---------------------------------------------------
                                               3166
Run Code Online (Sandbox Code Playgroud)

查询4

SELECT TO_DATE(SYSDATE, 'DD/MON/YYYY') - TO_DATE('01/JAN/2007') FROM DUAL;

TO_DATE(SYSDATE,'DD/MON/YYYY')-TO_DATE('01/JAN/2007')
-----------------------------------------------------
                                              -72732
Run Code Online (Sandbox Code Playgroud)

Jus*_*ave 6

永远不要打电话to_datedate.

假设您nls_date_format的设置为"DD-MON-RR",这似乎是基于您的第一个查询,当您运行TO_DATE(SYSDATE, 'DD/MON/YYYY')以下操作时.

  1. to_date不接受a date作为参数,它只需要一个varchar2.所以Oracle必须进行隐式转换date才能varchar2使用你的会话nls_date_format.
  2. 这会将电话转换为 to_date( '02-SEP-15', 'DD/MON/YYYY' )
  3. 由于您的字符串输入参数具有2位数年份,但您的格式掩码指定了4位数年份,因此您会得到非常意外的结果.它不是被解释为2015年,而是被解释为第15年(2000年前的罗马帝国时期).
  4. 现在你从0015年减去2007年,你得到的差异只有1,991年(确切地说是727,321天).

这个故事的寓意 - 从不打电话to_datedate.它已经是一个date.将它转换为a date是没有意义的.如果您只想将a的时间部分设置date为午夜,请使用trunc.不要投了date一个varchar2date.