您的位置:首页 > 产品设计 > UI/UE

ORA-01855: AM/A.M. or PM/P.M. required问题排查与解析

2014-03-24 20:45 288 查看


ORA-01855: AM/A.M. or PM/P.M. required问题排查与解析

【转自】http://271788203.iteye.com/blog/688303

1.【问题现象】

在中文Windows环境的SQL*Plus中使用如下日期操作SQL时报错。具体报错信息如下:

sec@ora10g> insert into t values (TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM'));

insert into t values (TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM'))

*

第 1 行出现错误:

ORA-01855: AM/A.M. or PM/P.M. required

sec@ora10g> select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual;

select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual

*

第 1 行出现错误:

ORA-01855: AM/A.M. or PM/P.M. required

2.【问题原因】

在本地NLS_DATE_LANGUAGE参数指定的语言中没有找到“AM”这样的时间定义,也就是说在具体的国家语言下此类“AM”的定义是不相同的,比如,在中文“SIMPLIFIED CHINESE”中就应该指定为“上午/下午”,在美国的语言中就应该指定为“A.M.
/ P.M.”,在英国语言或西欧语言中就要指定为“AM/PM”。注意其中的区别。

这里给出一种查询NLS_DATE_LANGUAGE参数的方法:

sec@ora10g> col PARAMETER for a30

sec@ora10g> col VALUE for a30

sec@ora10g> select * from v$nls_parameters;

PARAMETER VALUE

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

NLS_LANGUAGE SIMPLIFIED CHINESE

NLS_TERRITORY CHINA

NLS_CURRENCY ¥

NLS_ISO_CURRENCY CHINA

NLS_NUMERIC_CHARACTERS .,

NLS_CALENDAR GREGORIAN

NLS_DATE_FORMAT DD-MON-RR

NLS_DATE_LANGUAGE SIMPLIFIED CHINESE

NLS_CHARACTERSET AL32UTF8

NLS_SORT BINARY

NLS_TIME_FORMAT HH.MI.SSXFF AM

NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM

NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR

NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR

NLS_DUAL_CURRENCY ¥

NLS_NCHAR_CHARACTERSET UTF8

NLS_COMP BINARY

NLS_LENGTH_SEMANTICS BYTE

NLS_NCHAR_CONV_EXCP FALSE

已选择19行。

3.【[b]问题处理】 方法很简单,第一类处理方法就是严格按照具体国家语言的定义格式书写特定的时间字符串,另一类处理方法是修改NLS_DATE_LANGUAGE参数以便适应某一种日期字符串的写法。下面从这两类处理思想出发,给出三种可行的处理方法。[/b]

1)第一种方法:将原字符串中的“AM”修改为中国特色的的“上午”

sec@ora10g> select TO_Date( '22/10/2009 12:00:00 上午', 'DD/MM/YYYY HH:MI:SS AM') from dual;

TO_DATE('22/10

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

22-10月-09

sec@ora10g> alter session set NLS_DATE_FORMAT='MM/DD/YYYY HH:MI:SS AM';

会话已更改。

sec@ora10g> select TO_Date( '22/10/2009 12:00:00 上午', 'DD/MM/YYYY HH:MI:SS AM') from dual;

TO_DATE('22/10/200912:00

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

10/22/2009 12:00:00 上午

2)第二种处理方法:直接在session中修改NLS_DATE_LANGUAGE参数,即刻生效。

(1)修改NLS_DATE_LANGUAGE为“AMERICAN”

sec@ora10g> alter session set NLS_DATE_LANGUAGE = 'AMERICAN';

会话已更改。

(2)再一次尝试查询,此时已经不再报错

sec@ora10g> select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual;

TO_DATE('10/

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

22-OCT-09

(3)格式化一下日期格式,以便更加清晰的查看结果。

sec@ora10g> alter session set NLS_DATE_FORMAT='MM/DD/YYYY HH:MI:SS AM';

会话已更改。

sec@ora10g> select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual;

TO_DATE('10/22/200912:

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

10/22/2009 12:00:00 AM

3)第三种方法:修改Windows注册表中的NLS_LANG参数,以便达到迂回的修改NLS_DATE_FORMAT参数的目的

(1)进入Windows注册表方法

点击Windows操作系统的左下角的“开始”(“start”),然后点击“运行”(Run),最后输入“regedit”回车后便可进入到注册表界面。

(2)在注册表中按照下面的过程导航,即可定位到NLS_LANG变量

“My Computer” --> “HKEY_LOCAL_MACHINE” --> “SOFTWARE” --> “ORACLE” --> “KEY-OraDb10g_home1”

此时在注册表的右侧就能发现“NLS_LANG”的身影了

(3)双击“NLS_LANG”,把内容替换为“AMERICAN_AMERICA.ZHS16GBK”或“AMERICAN_CHINA.ZHS16GBK”即可(NLS_LANG的第一部分“语言”起作用)。

(4)验证查询

sec@ora10g> select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual;

TO_DATE('10/

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

22-OCT-09

sec@ora10g> alter session set NLS_DATE_FORMAT='MM/DD/YYYY HH:MI:SS AM';

Session altered.

sec@ora10g> select TO_Date( '10/22/2009 12:00:00 AM', 'MM/DD/YYYY HH:MI:SS AM') from dual;

TO_DATE('10/22/200912:

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

10/22/2009 12:00:00 AM

4.小结

Oracle的日期操作本身相对其他数据类型操作来说复杂很多,在日常的使用过程中要多加总结与记录。

鉴于本文中提到的问题,在书写脚本的时候或使用工具生成脚本的时候,一定要注意脚本中日期类字符串的书写格式。以防因此导致数据无法录入。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐