2014-01-16 102 views
11

我尝试从日期筛选表中选择数据时遇到问题。例如:ORA-01843不是一个有效的月份 - 比较日期

SELECT * FROM MYTABLE where MYTABLE.DATEIN = '23/04/49';

Oracle错误是:

Informe de error: 
Error SQL: ORA-01843: mes no válido 
01843. 00000 - "not a valid month" 
*Cause:  
*Action: 

可能表的源数据被破坏,在这种情况下:我怎样才能解决这个问题呢? 我可以将此日期更改为null吗?

此选择的结果select * from nls_session_parameters; ,是:

PARAMETER      VALUE         
------------------------------ ---------------------------------------- 
NLS_LANGUAGE     SPANISH         
NLS_TERRITORY     SPAIN          
NLS_CURRENCY     ¿           
NLS_ISO_CURRENCY    SPAIN          
NLS_NUMERIC_CHARACTERS   ,.          
NLS_CALENDAR     GREGORIAN         
NLS_DATE_FORMAT    DD/MM/RR         
NLS_DATE_LANGUAGE    SPANISH         
NLS_SORT      SPANISH         
NLS_TIME_FORMAT    HH24:MI:SSXFF        
NLS_TIMESTAMP_FORMAT   DD/MM/RR HH24:MI:SSXFF     
NLS_TIME_TZ_FORMAT    HH24:MI:SSXFF TZR       
NLS_TIMESTAMP_TZ_FORMAT  DD/MM/RR HH24:MI:SSXFF TZR    
NLS_DUAL_CURRENCY    ¿           
NLS_COMP      BINARY         
NLS_LENGTH_SEMANTICS   BYTE          
NLS_NCHAR_CONV_EXCP   FALSE 

谢谢!

+0

之间的使用格式为da te似乎是美国格式:“月/日/年”,所以23月份是错误的。尝试'04/23/49' –

+0

日期格式为'DD/MM/YY',如果尝试更改'MM/DD/YY'的格式,则相同。 – Davidin073

回答

17

您应该使用to_date函数http://www.techonthenet.com/oracle/functions/to_date.php

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49', 'DD/MM/YY'); 
+5

我会说:应该使用。 比较日期时总是使用格式。否则它会在某个系统上出错。 – Rene

+0

是的雷内。但是与TO_DATE函数一样或者没有格式,或者没有它。错误是相同的 - > 01843. 00000 - “不是有效的月份”。 – Davidin073

+0

您正在使用date类型的“mytable.datein”列吗? – Rene

8

你是一个日期列比较字符串文字。在这种情况下,Oracle会尝试使用默认日期格式将文字转换为日期。 依赖这种行为是一种糟糕的做法,因为如果DBA更改某些配置,Oracle会在未来的修订中破坏某些内容,则此默认设置可能会发生变化等。

相反,您应该始终将文字显式转换为日期并说明您正在使用的格式:

SELECT * FROM MYTABLE WHERE MYTABLE.DATEIN = TO_DATE('23/04/49','MM/DD/YY'); 
+0

当然Mureinik,但如果你有一个表与这个日期:23/04/49,并尝试与先前的选择搜索,你会得到同样的错误? – Davidin073

0

在对其中一个答案的评论中,您提到to_date格式不起​​作用。在另一条评论中,你解释了该表是通过DBLINK访问的。

显然,其他系统包含Oracle无法接受的无效日期。解决这个问题在其他dbms(或任何你的dblink链接)和你的查询将工作。

说了这些之后,我同意其他的观点:总是使用to_date格式来将字符串文字转换为日期。也不要只使用两位数字一年。例如'23/04/49'意味着系统中的2049(格式为RR),但它会使读者感到困惑(正如您从答案中提出的建议格式与YY一样)。

+0

我无法访问源表。所以它不可能修改这些数据。它的一年的无关数据,因为它在本月的错误。 – Davidin073

+0

不,也许你不能。但是你可以报告这个,所以_somebody_可以在其他系统中修复这个问题。至于这一年:这与错误无关。这只是一个普遍的建议。 –

+0

好的,所以我会报告这个错误。感谢您的推荐,Thorsten,但它的正常必须使用其他人以前创建的代码,并且无法修改某些实现。 – Davidin073

0

如果源日期包含分钟和秒部分,则日期比较将失败。 您需要使用to_char和目标日期将源日期转换为所需的格式。

3

我知道这有点晚,但我有类似的问题。 SQL * Plus成功执行查询,但Oracle SQL Developer显示ORA-01843:不是有效的月份错误。

SQL * Plus似乎知道我使用的日期是有效格式,而Oracle SQL Developer需要明确告知我的日期格式是什么格式。

SQL*Plus statement: 
select count(*) from some_table where DATE_TIME_CREATED < '09-12-23'; 

VS

Oracle SQL Developer statement: 
select count(*) from some_table where DATE_TIME_CREATED < TO_DATE('09-12-23','RR-MM-DD'); 
0

万一这可以帮助,我通过检查服务器的日期格式解决了这个:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT'; 

然后通过下面的对比(左字段是日期+时间):

AND EV_DTTM >= ('01-DEC-16') 

我正在尝试与TO_DATE,但不断收到错误。但是,当我匹配我的字符串与NLS_DATE_FORMAT和删除TO_DATE,它的工作...

0

如果您不需要查看准确的时间戳,使用

SELECT * FROM MYTABLE WHERE trunc(DATEIN) = TO_DATE('23-04-49','DD-MM-YY'); 

否则,您可以使用

SELECT * FROM MYTABLE WHERE DATEIN = TO_DATE('23-04-49 20:18:07','DD-MM-YY HH24:MI:SS'); 

在这里,您可以使用硬编码的日期,如果你直接比较,那么你必须使用DD-MM-YY HH24:MI:SS否则你可能会得到ORA-01849:小时必须在1到12

相关问题