DATE类型默认格式的设置
今天在工作中发现一个问题,同样的代码在同事的机子上可以执行,在我的机子上报错。在分析了之后,发现是date类型数据的默认格式问题引起的。到网上查了一下,发现遇到这个问题的人算是不少,但是能说清楚的也没几个人,所以专门研究了一下这个问题,基本上得到了答案,具体的过程如下:
首先把问题重现一下,SQL做了一些简化,代码如下:
SQL > select to_date(to_char(last_day(add_months(sysdate,-1)),'YYYY-MM-DD')) from dual;
*
ERROR at line 1:
ORA-01861: literal does not match format string
发现应该是date类型的默认格式的问题。在同事机子上的默认格式本身就是'YYYY-MM-DD'的,所以在to_date函数后面,对'YYYY-MM-DD'格式的char无需再指定date格式类型,但是如果char格式与默认不一致,则会报错。
date类型的默认格式由启动参数 nls_date_format 指定
SQL > select * from nls_database_parameters where PARAMETER = 'NLS_DATE_FORMAT';
PARAMETER VALUE
--------------- ----------------
NLS_DATE_FORMAT DD-MON-RR
SQL
> select sysdate from dual;
SYSDATE
-----------
2008-NOV-05
发现系统的默认NLS_DATE_FORMAT参数值为DD-MON-RR。
再查看当前DATABASE的该参数:
SQL > show parameter nls_date_format
NAME TYPE VALUE
------------------- ----------- --------------------
nls_date_format string
发现当前数据库未设定该参数。
由于这个是系统的启动参数,不能直接用alter database来修改,所以可以通过修改当前session来暂时实验一下:
SQL
> alter session set nls_date_format='yyyy-mm-dd';
Session altered.
SQL
> select sysdate from dual;
SYSDATE
----------
2008-11-05
再试一下之前的那段SQL
SQL > select to_date(to_char(last_day(add_months(sysdate,-1)),'YYYY-MM-DD')) from dual;
TO_DATE(TO
----------
2008-10-31
如果需要一直都这样显示,则可以修改注册表、添加环境变量,或直接修改启动参数文件。