欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

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

程序员文章站 2023-12-25 19:44:27
...

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

早上收到开发人员发来的邮件,说在一个测试环境中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

一看错误信息是ORA-01839: date not valid for month specified。首先想到可能是数据有问题导致在使用TO_DATE报错。不管怎样先去求证下是不是真的存在该错误。首先连接上说执行报错的库,执行SQL,果然如开发人员所说报错。接着连接上说执行正常的库,执行SQL,果然Oracle很友好的返回了结果。既然错误事实存在,那就要去找出导致错误的原因了。

按照对错误的第一反应,先去比对两边的数据是否一样。比对结果有点令人失望,两边的数据完全一模一样。难道是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执行正常,至此问题解决。

上一篇:

下一篇: