分析ORA-12899, 迁移数据时遇到的多字节问题
2013-03-26 14:56
344 查看
一,背景回顾:
手头有一个同事使用exp导出的dump文件,我用其导入自己的测试环境时,有一小部分数据遇到ORA-12899而不能被导入。源数据库字符集: ZHS16GBK
exp客户端NLS_LANG: SIMPLIFIED CHINESE_CHINA.ZHS16GBK
目标数据库字符集: AL32UTF8
二,实验重演:
创建测试库A,使用字符集 ZHS16GBK (test4)创建测试库B,使用字符集 AL32UTF8 (test3)
然后使用exp imp,expdp impdp做测试
在本例中,为了避免字符集转换,需要设定正确的NLS_LANG
Setp1. 在ZHS16BGK数据库创建测试表及数据
库A:[oracle@redhat ~]$ export ORACLE_SID=test4
[oracle@redhat ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@redhat ~]$ sqlplus pjh/123
SQL*Plus: Release 11.2.0.3.0 Production on 星期二 3月 26 13:17:28 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_CHARACTERSET ZHS16GBK
SQL> show user
USER is "PJH"
SQL> create table test1 (id number, name varchar2(8));
Table created.
SQL> insert into test1 values (1,'我');
1 row created.
SQL> insert into test1 values (2,'我是');
1 row created.
SQL> insert into test1 values (3,'我是谁');
1 row created.
SQL> insert into test1 values (4,'我是a');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test1;
ID NAME
---------- ---------------
1 我
2 我是
3 我是谁
4 我是a
Step2. 分别使用exp 与 expdp导出test1表,供后续导入使用
使用exp导出:
[oracle@redhat ~]$ export ORACLE_SID=test4[oracle@redhat ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@redhat ~]$ exp system/oracle file=/tmp/test1.dump tables=pjh.test1
Export: Release 11.2.0.3.0 - Production on 星期二 3月 26 13:40:53 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in ZHS16GBK character set and AL16UTF16 NCHAR character set
About to export specified tables via Conventional Path ...
Current user changed to PJH
. . exporting table TEST1 4 rows exported
Export terminated successfully without warnings.
[oracle@redhat ~]$
使用expdp导出:
[oracle@redhat ~]$ export ORACLE_SID=test4[oracle@redhat ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@redhat ~]$ expdp pjh/123 dumpfile=test1.dp directory=dp_tmp job_name=pjh1
Export: Release 11.2.0.3.0 - Production on 星期二 3月 26 13:37:59 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
启动 "PJH"."PJH1": pjh/******** dumpfile=test1.dp directory=dp_tmp job_name=pjh1
正在使用 BLOCKS 方法进行估计...
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
使用 BLOCKS 方法的总估计: 64 KB
处理对象类型 SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE
处理对象类型 SCHEMA_EXPORT/TABLE/COMMENT
处理对象类型 SCHEMA_EXPORT/TABLE/INDEX/INDEX
处理对象类型 SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
处理对象类型 SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
. . 导出了 "PJH"."TEST1" 5.445 KB 4 行
已成功加载/卸载了主表 "PJH"."PJH1"
******************************************************************************
PJH.PJH1 的转储文件集为:
/tmp/test1.dp
作业 "PJH"."PJH1" 已于 13:39:05 成功完成
[oracle@redhat ~]$
Step3. 分别使用imp与impdp将test1导入AL32UTF8的数据库
库B:SQL> select * from v$nls_parameters where parameter='NLS_CHARACTERSET';
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_CHARACTERSET AL32UTF8
SQL> create user pjh identified by "123";
User created.
SQL> grant connect,resource to pjh;
Grant succeeded.
SQL>
使用imp导入:
[oracle@redhat ~]$ export ORACLE_SID=test3[oracle@redhat ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@redhat ~]$ imp system/oracle file=/tmp/test1.dump fromuser=pjh touser=pjh
Import: Release 11.2.0.3.0 - Production on 星期二 3月 26 13:59:07 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export file created by EXPORT:V11.02.00 via conventional path
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
import server uses AL32UTF8 character set (possible charset conversion)
. importing PJH's objects into PJH
. . importing table "TEST1"
IMP-00019: row rejected due to ORACLE error 12899
IMP-00003: ORACLE error 12899 encountered
ORA-12899: 列 "PJH"."TEST1"."NAME" 的值太大 (实际值: 9, 最大值: 8)
Column 1 3
Column 2 我是谁 3 rows imported
Import terminated successfully with warnings.
[oracle@redhat ~]$
[oracle@redhat ~]$ sqlplus pjh/123
SQL*Plus: Release 11.2.0.3.0 Production on 星期二 3月 26 13:59:59 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from test1;
ID NAME
---------- ----------------
1 我
2 我是
4 我是a
尝试用impdp导入:
[oracle@redhat ~]$ export ORACLE_SID=test3[oracle@redhat ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@redhat ~]$ impdp pjh/123 dumpfile=test1.dp directory=dp_tmp job_name=pjh1
Import: Release 11.2.0.3.0 - Production on 星期二 3月 26 14:03:11 2013
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
已成功加载/卸载了主表 "PJH"."PJH1"
启动 "PJH"."PJH1": pjh/******** dumpfile=test1.dp directory=dp_tmp job_name=pjh1
处理对象类型 SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE
处理对象类型 SCHEMA_EXPORT/TABLE/TABLE_DATA
ORA-02374: conversion error loading table "PJH"."TEST1"
ORA-12899: value too large for column NAME (actual: 9, maximum: 8)
ORA-02372: data for row: NAME : 0X'CED2CAC7CBAD'
. . 导入的 "PJH"."TEST1" 5.445 KB 3 用完了 4 行
作业 "PJH"."PJH1" 已于 14:03:19 成功完成
[oracle@redhat ~]$ sqlplus pjh/123
SQL*Plus: Release 11.2.0.3.0 Production on 星期二 3月 26 14:03:34 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select * from test1;
ID NAME
---------- ----------------
1 我
2 我是
4 我是a
第三行同样导入失败! exp与expdp均有此问题。
三,原因分析:
一个汉字(包括中文标点、符号)在不同字符集的数据库中占用的字节数是不同的。在ZHs16GBK的数据库中,一个汉字占用2个字节,但是在AL32UTF8数据库中,一个汉字占用3个字节。
本例中 ZHS16GBK数据库中test1表的name字段长度是8个字节。 导入到AL32UTF8数据库时,表的定义不会改变,即name字段仍然是8个字节。 但是在AL32UTF8中8个字节不能够保存下3个汉字。
以下可以非常直观的看到区别:
在ZHS16GBK数据库中
SQL> select dump('我是谁',1106) from dual;
DUMP('我是谁',1106)
-----------------------------------------------------
Typ=96 Len=6 CharacterSet=ZHS16GBK: ce,d2,ca,c7,cb,ad
在AL32UFT8数据库中
SQL> select dump('我是谁',1106) from dual;
DUMP('我是谁',1106)
--------------------------------------------------------------------------------
Typ=96 Len=9 CharacterSet=AL32UTF8: e6,88,91,e6,98,af,e8,b0,81
当然为了输入中文,在环境变量设置 NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK" 是必须的!
相关文章推荐
- 2014.1.16实施数据迁移时遇到的问题(ORA-00214和ORA-39700问题解决)
- 数据迁移中遇到的问题
- 面试的时候经常遇到数据类型字节大小,字节对齐的问题,现整理如下
- SVN迁移数据遇到的问题
- 不同版本mysql数据迁移过程所遇到的问题及解决办法
- 数据分析实践:遇到的问题及感想
- “数据中心迁移到IDC数据中心”最怕遇到这几个问题
- stm32串口发送数据,丢失字节问题分析
- 分析Mysql大量数据导入遇到的问题以及解决方案
- 从临时表返回数据时遇到的问题(ORA-08103: object no longer exists)
- “数据中心迁移到IDC数据中心”最怕遇到这几个问题
- sqoop从mysql迁移数据到hive中遇到的问题
- 从临时表返回数据时遇到的问题(ORA-08103: object no longer exists)
- MongoDB数据量大于2亿后遇到的问题 及原因分析
- python数据分析:charts使用中遇到的问题
- hadoop使用pig进行数据分析时遇到的问题(10020号端口问题,连接拒绝)
- codis迁移槽位遇到value过大的数据导致redis进程堵塞问题
- 关于EXP-00056: 遇到 ORACLE 错误 1455 ORA-01455: 转换列溢出整数数据类型 EXP-00000: 导出终止失败 的问题解决方法整理
- 用SPSS做数据分析时遇到的几个小问题——解决方法!
- Excel数据迁移到SQL Server遇到的若干问题