今天在工作中发现一个问题,同样的代码在同事的机子上可以执行,在我的机子上报错。
做了一些简化之后的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
****************************************************
如果需要一直都这样显示,则可以 修改注册表、添加环境变量、直接修改启动参数文件
-The End-