1

我有以下查询:

SELECT to_date(to_char(to_date('01-FEB-1949'))) FROM DUAL;  
/*this returns 2/1/2049. */

SELECT to_date(to_char(to_date('01-FEB-1949'),'dd-MON-yyyy')) FROM DUAL; 
/*this returns 2/1/1949.*/

为什么第一个返回年份2049而不是1949

通过谷歌搜索,我发现我可以通过更改key注册表“强制”客户日期格式成为一种愿望:

KEY_OraClient11g_home1
NLS_DATE_FORMAT : YYYY/MM/DD
4

1 回答 1

5

您在两个版本中都进行了多次隐式日期转换。这个:

SELECT to_date(to_char(to_date('01-FEB-1949'))) FROM DUAL; 

相当于:

SELECT to_date(to_char(to_date('01-FEB-1949', <NLS_DATE_FORMAT>),
    <NLS_DATE_FORMAT>, <NLS_DATE_FORMAT>)) FROM DUAL;

而第二个查询将其中一个替换为特定格式。它看起来像您的默认格式 - 我相信您可以在 Toad 首选项中设置,而无需直接修改注册表;目前尚不清楚您是否正在修改与 Toad - is 相关的内容DD-MON-RR,如将其插入这些查询所示:

SELECT to_date(to_char(to_date('01-FEB-1949','DD-MON-RR'),
        'DD-MON-RR'),'DD-MON-RR') AS date1,
    to_date(to_char(to_date('01-FEB-1949','DD-MON-RR'),
        'dd-MON-yyyy'),'DD-MON-RR') AS date2 FROM DUAL;

DATE1                            DATE2
February, 01 2049 00:00:00+0000  February, 01 1949 00:00:00+0000

SQL 小提琴

您可以在此 SQL Fiddle中看到,在第一个版本中,日期显示为带有年份的字符串,49而不是1949,然后通过RR掩码将其解释为2049,这是预期的行为。

短版:永远不要依赖隐式日期转换或 NLS 日期格式掩码。

于 2013-05-30T23:40:20.783 回答