一、问题说明
有如下两个数据库:
旧库 --- DB1(有数据 )
新库 --- DB2(无数据 )
现通过expdp命令导出DB1的数据,再通过impdp导入数据至DB2,在导入数据时有如下报错:
ORA-39083: Object type TABLE:"RUI"."TEST" failed to create with error:
ORA-00910: specified length too long for its datatype
经检查发现,是因为 "RUI"."TEST" 表有字段类型为NVARCHA2(4000)。
测试新建含 NVARCHA2(4000) 字段表,报错如下:
SQL> create table ruitest (a nvarchar2(4000));
create table ruitest (a nvarchar2(4000))
*
ERROR at line 1:
ORA-00910: specified length too long for its datatype
二、问题分析
同样是 NVARCHA2(4000),为什么在DB1可以创建成功,但在DB2却创建失败呢?
1.查看字符集
select *from nls_database_parameters;
对比 DB1 和 DB2 的查询结果,发现参数 NLS_NCHAR_CHARACTERSET 的值不同(DB1:UTF8 DB2:AL16UTF16)
回溯原因,是因为在使用 dbca 创建 database 时,使用的是 Typical configuration ,如下图:
导致National character set 保留了默认值,等效使用 Advanced configuration 做出了如下配置:
三、处理方法
1.解决思路
可通过修改参数 max_string_size 实现创建含NVARCHA2(4000)字段的表。
在Oracle Database 12c中,我们可以为varchar2、nvarchar2和RAW数据类型指定32767 bytes 的最大长度了, 以便用户将更长的字符串存储在数据库中。
在12c之前的版本中,varchar2和nvarchar2数据类型的最大长度是4000 bytes,而raw是2000 bytes。
在12c之后的版本中,参数MAX_STRING_SIZE控制扩展数据类型extended data type的最大长度:
- STANDARD 代表12c之前的长度限制,即varchar2、nvarchar2 4000 bytes, raw 是2000 bytes
- EXTENDED 代表12c 32k strings新特性,varchar2、nvarchar2、raw最大长度32k bytes
Extended character data types 扩展字符类型存在以下的限制:
-不支持cluster table 簇表和index-organized tables索引组织表
-不支持intrapartition的并行DDL、UPDATE和DELETE DML
-不支持在Automatic Segment Space Management (ASSM)表空间上的intrapartition parallel direct-path inserts
2.处理方法
SQL> ALTER SYSTEM SET MAX_STRING_SIZE = EXTENDED SCOPE=SPFILE;
SQL> shutdown immediate;
SQL> startup upgrade;
SQL> @$ORACLE_HOME/rdbms/admin/utl32k;
SQL> shutdown immediate;
SQL> startup
记得检查有没有产生失效对象:
SQL> select count(*) from dba_objects where status<>'VALID';
COUNT(*)
----------
0
3.效果验证
再次尝试,可成功建表:
SQL> create table ruitest (a nvarchar2(4000));
Table created.
SQL> create table ruitest1(a nvarchar2(6000));
Table created.