Posts in category database

Oracle 数据库导入时 ORA-12899 错误的处理

原因分析和 http://wuhuizhong.iteye.com/blog/740553 一样:

一般设计数据库的时候,我们都考虑一个汉字占用两个字节。所以设计数据库的时候,如果认为某字段最长要存四个汉字,该字段都会定义为varchar2(8)。

SQL> create table t1 (col1 varchar2(8));
Table created.

但是测试插入三个汉字的时候就报错了。

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> select * from nls_database_parameters where parameter like 'NLS%CHARACTERSET';
PARAMETER                 VALUE
------------------------- --------------------
NLS_CHARACTERSET          UTF8
NLS_NCHAR_CHARACTERSET    UTF8

原来数据库使用的是UTF8字符集,难怪一个汉字占用3个字节。这样一来原先按一个汉字占两个字节设计的数据库,应用的时候很多字段都会因长度不够,出现ORA-12899错误。

解决办法比较直接,就是直接修改 dump 文件中数据库表定义的文本,把 CHAR(n) 改为 NCHAR(n), VARCHAR2(n) 改为 NVARCHAR2(n):

sed 's/ CHAR(/ NCHAR(/g'  export.dmp > export1.dmp
sed 's/ VARCHAR2(/ NVARCHAR2(/g'  export1.dmp > export2.dmp
# 在 Window 32 位平台上有 NVARCHAR2 不能大于 2000 的限制
sed 's/ NVARCHAR2(3000)/ NVARCHAR2(2000)/g'  export2.dmp > export3.dmp
sed 's/ NVARCHAR2(4000)/ NVARCHAR2(2000)/g'  export3.dmp > export4.dmp
sed 's/ NVARCHAR2(2200)/ NVARCHAR2(2000)/g'  export4.dmp > export5.dmp