尝试从按日期过滤的表中选择数据时出现问题。例如:
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
谢谢!
答案 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)