ORA-01855: 要求 AM/A.M. 或 PM/P.M.

1.【问题现象】

在中文Windows环境的SQL*Plus中使用如下日期操作SQL时报错。具体报错信息如下:
SQL> 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

SQL> 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参数的方法:
SQL> col PARAMETER for a30
SQL> col VALUE for a30
SQL> 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.【问题处理】 方法很简单,第一类处理方法就是严格按照具体国家语言的定义格式书写特定的时间字符串,另一类处理方法是修改NLS_DATE_LANGUAGE参数以便适应某一种日期字符串的写法。下面从这两类处理思想出发,给出三种可行的处理方法。
1)第一种方法:将原字符串中的“AM”修改为中国特色的的“上午”
SQL> 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

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

会话已更改。

SQL> 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参数,即刻生效。

注意:设置要在对应的用户下才能起到作用。比如你是在scott用户下插入数据,那么你更改的NLS_DATE_LANGUAGE也要在scott用户下设置才有效。不能在system下设置!因为每个用户都有各自的v$nls_parameters,所以不能想当然的以为在system用户下的设置对scott用户有效。


(1)修改NLS_DATE_LANGUAGE为“AMERICAN”
SQL> alter session set NLS_DATE_LANGUAGE = 'AMERICAN';

会话已更改。

(2)再一次尝试查询,此时已经不再报错
SQL> 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)格式化一下日期格式,以便更加清晰的查看结果。
SQL> alter session set NLS_DATE_FORMAT='MM/DD/YYYY HH:MI:SS AM';

会话已更改。

SQL> 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)验证查询
SQL> 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

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

Session altered.

SQL> 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的日期操作本身相对其他数据类型操作来说复杂很多,在日常的使用过程中要多加总结与记录。
鉴于本文中提到的问题,在书写脚本的时候或使用工具生成脚本的时候,一定要注意脚本中日期类字符串的书写格式。以防因此导致数据无法录入


来源:http://www.51testing.com/?uid-117986-action-viewspace-itemid-213833


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值