ORA-12899錯誤解決記錄


做極限測試時 應用程序打印出ORA-12899: 列 "xxx"."表"."字段" 的值太大 (實際值: 21, 最大值: 20)的錯誤

原來數據庫使用的是UTF8字符集,難怪一個漢字占用3個字節。這樣一來原先按一個漢字占兩個字節設計的數據庫,應用的時候很多字段都會因長度不夠,出現ORA-12899錯誤。

可以將字符集改為 ZHS16GBK即可解決。

轉解決方案

解決方案: 
修改oracle 10g的字符集
修改數據庫字符集為:ZHS16GBK
查看服務器端字符集SQL > select * from V$NLS_PARAMETERS
修改:$sqlplus /nolog  www.2cto.com  
SQL>conn / as sysdba
若此時數據庫服務器已啟動,則先執行 SHUTDOWN IMMEDIATE 命令關閉數據庫服務器,
然后執行以下命令:
SQL>shutdown immediate
SQL>STARTUP MOUNT
SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION
SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0
SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0
SQL>ALTER DATABASE OPEN
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK
ERROR at line 1:ORA-12721: operation cannot execute when other sessions are active
若出現上面的錯誤,使用下面的辦法進行修改,使用INTERNAL_USE可以跳過超集的檢查:
SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK
SQL>SHUTDOWN IMMEDIATE
SQL>STARTUP
 
引申閱讀:http://blog.sina.com.cn/s/blog_6a7447840100mjcc.html

不能把數據庫的字符集改成ZHS16GBK。因為系統要求不僅能支持中文,還要能支持其他亞洲字符。這樣CHARACTER SET就只能設這成UTF8或AL32UTF8,這兩種字符集每個漢字占用的字節數分別是3和4,都不是2。
更改所有CHAR/VARCHAR字段的長度也不現實。整套系統是從其他公司買的產品,內含上千張表,逐個去修改字段不太可能。


查看參數NLS_LENGTH_SEMANTICS。
Oracl文檔中的說明:
Syntax: NLS_LENGTH_SEMANTICS = string
Range of values: BYTE | CHAR
NLS_LENGTH_SEMANTICS enables you to create CHAR and VARCHAR2 columns using either byte or character length semantics. Existing columns are not affected.
NCHAR, NVARCHAR2, CLOB, and NCLOB columns are always character-based. You may be required to use byte semantics in order to maintain compatibility with existing applications.
NLS_LENGTH_SEMANTICS does not apply to tables in SYS and SYSTEM. The data dictionary always uses byte semantics.


查看數據庫中該參數的設置。
SQL> select * from nls_database_parameters where parameter like 'NLS%SEMANTICS';
PARAMETER                 VALUE
------------------------- --------------------
NLS_LENGTH_SEMANTICS       BYTE

SQL> show parameter nls_length
NAME                                 TYPE       VALUE
------------------------------------ ---------- -------
nls_length_semantics                 string     BYTE


把該參數改成CHAR
SQL>alter system set NLS_LENGTH_SEMANTICS=BYTE scope=BOTH;

修改后查看參數。
SQL> show parameter nls_length
NAME TYPE VALUE
------------------------------------ ---------- -------
nls_length_semantics string CHAR

從新執行insert操作。
SQL> insert into t1 values('一二三');
insert into t1 values('一二三')
*
ERROR at line 1:
ORA-12899: value too large for column T1.COL1 (actual: 9, maximum:8)
還是出錯!

新創建一張表,再測試。
SQL> create table t2 (col1 varchar2(8));
表已創建。

SQL> insert into t2 values('一二三')
已創建 1 行。

SQL> select * from t2;
COL1
----------------
一二三

OK了

再查看t1和t2的表結構,可以發現一些差別。
SQL> desc t1
名稱                  是否為空? 類型
-------------------- -------- -------------------------
COL1                           VARCHAR2(8)

SQL> desc t2
名稱                  是否為空? 類型
-------------------- -------- -------------------------
COL1                           VARCHAR2(8 CHAR)


參數NLS_LENGTH_SEMANTICS改成CHAR以后,t2.col1列可以存儲8個漢字,英文字符也只能存儲8個。
SQL> insert into t2 values('一二三四五六七八');
已創建 1 行。

SQL> insert into t2 values('abcdefgh');
已創建 1 行。

SQL> insert into t2 values('abcdefghi');
insert into t2 values('abcdefghi')
*
ERROR 位於第 1 行:
ORA-12899: value too large for column T2.COL1 (actual: 9, maximum:8)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM