系统日期设置不正确导致的ORA-01839错误

2015-07-16 12:08:45 · 作者: · 浏览: 0

早上收到开发人员发来的邮件,说在一个测试环境中SQL执行报错,但相同的SQL在另一个测试环境中却执行经常,叫我帮忙分析一下原因。报错的SQL为:


SQL> select to_date(substr(cvalidate, 6, 10), 'MM-DD') from lcpol where polno='210010000123931';


select to_date(substr(cvalidate, 6, 10), 'MM-DD') from? lcpol where polno='210010000123931';


*


ERROR at line 1:


ORA-01839: date not valid for month specified


?


?按照对错误的第一反应,先去比对两边的数据是否一样。比对结果有点令人失望,两边的数据完全一模一样。难道是SQL本身存在问题?仔细分析下SQL,应该没错啊,虽然使用'MM-DD'格式化的写法不怎么好,但也应该不至于导致执行错误啊,况且在另外的库上是执行正确的。那问题到底处在哪呢?难道是两库的日期参数设置不一样?查看了一下,两个数据库的NLS_CHARACTERSET,


NLS_NCHAR_CHARACTERSET, NLS_DATE_LANGUAGE, NLS_DATE_FORMAT设置也是一样的。好吧,看来问题应该不在数据上。


?


?再回头来看一下,在条件polno='210010000123931'下的cvalidate是个什么值呢?



SQL> select cvalidate from lcpol where polno='210010000123931';? CVALIDATE ---------- 2012-02-29


看来该值确实也比较特殊,4年才会出现一次。但是特殊归特殊,也不应该报错了。想到如果直接用该值会怎样?嗯,那就试试看:



SQL>select to_date(substr('2012-02-29', 6, 10), 'MM-DD') from dual;


ERROR


-----------------------


ERROR at line 1:


ORA-01839: date not valid for month specified


?


SQL> select to_date(substr('2012-02-29', 6, 10), 'MM-DD') from dual;


?


TO_DATE(SU


----------


2012-02-29


测试结果还是一样。正一筹莫展之际,突然注意到虽然使用'MM-DD'来格式化日期,但是结果中仍然还有年的信息!想到当前的NLS_DATE_FORMAT为'YYYY-MM-DD',猜测Oracle会使用当前系统的日期来附加年的信息。难道是那台执行错误的库的系统日期不正确,马上查看一下,果然,系统日期是2013年!



$ date


Fri Mar? 1 18:45:13 CST 2013


马上联系系统管理小组帮忙修正系统日期。在系统日期修改正确后,SQL执行正常,至此问题解决。