ORA-01843无效月份 - 比较日期

时间:2014-01-16 08:56:00

标签: sql oracle date select

尝试从按日期过滤的表中选择数据时出现问题。例如:

  

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吗?

此选择的结果,从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 

谢谢!

12 个答案:

答案 0 :(得分:27)

您应该使用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');

答案 1 :(得分:8)

您正在将日期列与字符串文字进行比较。在这种情况下,Oracle会尝试使用默认日期格式将您的文字转换为日期。 依赖这种行为是一种不好的做法,因为如果DBA更改了某些配置,Oracle会在未来版本中破坏某些内容,则此默认值可能会发生变化等。

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

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

答案 2 :(得分: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');

答案 3 :(得分:3)

如果您不需要检查确切的时间戳,请使用

Intents

否则,您可以使用

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

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

答案 4 :(得分:1)

如果这有帮助,我通过检查服务器日期格式解决了这个问题:

SELECT * FROM nls_session_parameters WHERE parameter = 'NLS_DATE_FORMAT';

然后使用以下比较(左侧字段是日期+时间):

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

我正在尝试使用TO_DATE,但一直收到错误。但是当我将我的字符串与NLS_DATE_FORMAT匹配并删除TO_DATE时,它就有效了......

答案 5 :(得分:1)

ALTER会话集NLS_LANGUAGE ='AMERICAN';

答案 6 :(得分:0)

在对其中一个答案的评论中,您提到使用格式的to_date无济于事。在另一条评论中,您解释了该表是通过DBLINK访问的。

显然,其他系统包含Oracle无法接受的无效日期。修复此问题在其他dbms(或任何dblink)中,您的查询将起作用。

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

答案 7 :(得分:0)

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

答案 8 :(得分:0)

如果您使用的是命令行工具,那么也可以在外壳中进行设置。

在具有sh型外壳的linux上,您可以执行以下操作:

export NLS_TIMESTAMP_FORMAT='DD/MON/RR HH24:MI:SSXFF'

然后您可以使用命令行工具,它将使用指定的格式:

/path/to/dbhome_1/bin/sqlldr user/pass@host:port/service control=table.ctl direct=true

答案 9 :(得分:0)

尝试使用:

SELECT *
FROM MYTABLE
WHERE MYTABLE.DATEIN is not null 
AND MYTABLE.DATEIN = '23/04/49';

答案 10 :(得分:0)

虽然使用 TO_DATE 的答案是正确的,但我更喜欢使用 ANSI SQL 格式的日期: 日期 = 日期 '1949-04-23'

它适用于 Oracle 和其他符合 ANSI SQL 的 DBMS。如果您的应用程序与 DBMS 无关,这一点尤其重要。

答案 11 :(得分:-1)

使用 month 作为字符串。

示例:

(12-Apr-2002) or (12-April-2002)