尽量不要修改字符集
ORA-02374: ORA-12899:
初步估计为字符集差异导致.中文在UTF-8里占3个字节,ZHS16GBK里占2个字节
select * from V$NLS_PARAMETERS s where PARAMETER like 'NLS%CHARACTERSET';
SQL> select * from V$NLS_PARAMETERS s where PARAMETER like 'NLS%CHARACTERSET';
PARAMETER VALUE
-------------------------------------------------------------
NLS_CHARACTERSET ZHS16GBK
NLS_NCHAR_CHARACTERSET AL16UTF16
shutdown immediate;
STARTUP MOUNT;
ALTER SESSION SET SQL_TRACE=TRUE;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; ----记得调回去
ALTER SYSTEM SET AQ_TM_PROCESSES=0; --这个参数默认就是0
ALTER DATABASE OPEN;
ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK; ---报字符集不兼容,此时用INTERNAL_USE指令不对字符集超集进行检查
重启数据库后,可正常导入;
通常会查询NLS_CHARACTERSET(数据库字符集),NLS_NCHAR_CHARACTERSET(国家字符集),应该要存储多种语言,需要字符集为UTF-8。
查看没问题的DB里 FieldA varchar2(10 char)
查看有问题的DB里 FieldA varchar2(10)
(没出现问题之前还真没注意到这两种定义是有区别的。。。)
UTF-8里一个中文字符是3 bytes,从上面的定义可以看出来,如果char/byte 定义导致的可存储数据长度相差很大了。
设置参数NLS_LENGTH_SEMANTICS可以在create table时对CHAR 或者VARCHAR2列指定使用字节(byte)或者字符(character)来定义长度。
NCHAR, NVARCHAR2, CLOB, and NCLOB 列都是基于字符(character)的。
NLS_LENGTH_SEMANTICS不会影响到SYS和SYSTEM用户表,数据字典定义都使用字节(byte)。
可以在定义列时候显示指定使用字节(byte)或者字符(character)来定义长度:
CHAR(10 BYTE) - 无论NLS_LENGTH_SEMANTICS设置成什么,都使用字节(byte)。
CHAR(10 CHAR) - 无论NLS_LENGTH_SEMANTICS设置成什么,都使用字符(char)。
数据库字符集和国家字符集区别
客户端字符集
oracle@s11sp4x64:/orasoft/02_eicqmdb> echo $NLS_LANG
AMERICAN_AMERICA.zhs16gbk