【問題處理】ORA-01855: AM/A.M. or PM/P.M. required問題排查與解析
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.【問題處理】 方法很簡單,第一類處理方法就是嚴格按照具體國家語言的定義格式書寫特定的時間字串,另一類處理方法是修改NLS_DATE_LANGUAGE引數以便適應某一種日期字串的寫法。下面從這兩類處理思想出發,給出三種可行的處理方法。
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的日期操作本身相對其他資料型別操作來說複雜很多,在日常的使用過程中要多加總結與記錄。
鑑於本文中提到的問題,在書寫指令碼的時候或使用工具生成指令碼的時候,一定要注意指令碼中日期類字串的書寫格式。以防因此導致資料無法錄入。
Good luck.
-- The End --
在中文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.【問題處理】 方法很簡單,第一類處理方法就是嚴格按照具體國家語言的定義格式書寫特定的時間字串,另一類處理方法是修改NLS_DATE_LANGUAGE引數以便適應某一種日期字串的寫法。下面從這兩類處理思想出發,給出三種可行的處理方法。
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的日期操作本身相對其他資料型別操作來說複雜很多,在日常的使用過程中要多加總結與記錄。
鑑於本文中提到的問題,在書寫指令碼的時候或使用工具生成指令碼的時候,一定要注意指令碼中日期類字串的書寫格式。以防因此導致資料無法錄入。
Good luck.
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-617289/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- job處理緩慢的效能問題排查與分析
- SDK與問題排查
- crontab 問題檢查與處理
- Lotus notes問題與處理
- 【問題處理】“NOT IN”與“NULL”的邂逅Null
- 解析PHP處理換行符的問題PHP
- java問題排查Java
- JVM 問題排查JVM
- 框架問題排查框架
- 處理問題的方法
- perl中文處理問題
- 漢字處理問題?
- xml處理的問題XML
- 貨品問題處理
- [git] git問題處理Git
- Proxy Authorization Required 問題請教UI
- Java服務.問題排查.問題復現Java
- 線上FullGC問題排查實踐——手把手教你排查線上問題GC
- golang json處理問題GolangJSON
- 併發問題處理方式
- ASMCMD處理問題一則ASM
- mysql的處理能力問題MySql
- RMAN處理split block問題BloC
- mysql問題處理兩則MySql
- Oracle啟動問題處理Oracle
- mysql 問題處理二則MySql
- Oracle壞塊問題處理Oracle
- 資料處理--pandas問題
- Ubuntu無法解析域名DNS指向127.0.0.53問題處理UbuntuDNS
- 異常問題排查之旅
- Spark學習——問題排查Spark
- 利用greys排查java問題Java
- JVM問題排查步驟JVM
- 資料問題排查思路
- Linux排查JVM問題LinuxJVM
- Redis阻塞問題排查方向Redis
- Mysql show processlist 排查問題MySql
- 【問題追查】mc叢集寫入恍惚問題排查