oracle数据库字符集问题

一、什么是oracle字符集
oracle字符集实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。

影响oracle数据库字符集最重要的参数是NLS_LANG参数。
它的格式如下: NLS_LANG = language_territory.charset
它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。
其中:
Language:指定服务器消息的语言,影响提示信息是中文还是英文
Territory:指定服务器的日期和数字格式
Charset:指定字符集
如:AMERICAN_AMERICA.ZHS16GBK
从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。
所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。

NLS_LANG参数是否是环境变量中的NLS_LANG呢?
并不是。oracle环境变量中的NLS_LANG是定义客户端的字符集。
比如环境变量NLS_LANG=AMERICAN_AMERICA.ZHS16GBK但是数据库三个实例的字符集可以分别是:AMERICAN_AMERICA.AL32UTF8、AMERICAN_AMERICA.WE8ISO8859P1、AMERICAN_AMERICA.ZHS16GBK

国家字符集与数据库字符集
oracle数据库有国家字符集(national character set)与数据库字符集(database character set)之分。两者都是在创建数据库时需要设置的。国家字符集主要是用于NCHAR、NVARCHAR、NCLOB类型的字段数据,而数据库字符集使用很广泛,它用于:CHAR、VARCHAR、CLOB、LONG类型的字段数据。
并且国家字符集只能是AL16UTF16或UTF8,一般用AL16UTF16。

二、字符集命名规则
oracle的字符集命名遵循以下命名规则:
<Language><bit size><encoding>
即:<语言><比特位数><编码>
比如:ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集。

三、字符集的查询
服务端:

select userenv('language') from dual;

客户端:

echo $NLS_LANG

国家字符集:

select * from v$nls_parameters;

NLS_CHARACTERSET为服务端字符集,NLS_NCHAR_CHARACTERSET为国家字符集。

四、字符集改动
oracle字符集的改动只能子集往超集方向改,这样才不会有兼容问题。比如WE8ISO8859P1和ZHS16GBK不是子集和超集的关系。
所以说最好在数据库创建时就指定好字符集。

修改字符集方法:
例如将实例的字符集从WE8ISO8859P1改为ZHS16GBK。

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;
SQL>alter database national character set ZHS16GBK;
SQL>shutdown immediate;
SQL>startup;

执行过程:

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.

Total System Global Area  281018368 bytes
Fixed Size		    2020160 bytes
Variable Size		   96472256 bytes
Database Buffers	  176160768 bytes
Redo Buffers		    6365184 bytes
Database mounted.
SQL> alter system enable restricted session;

System altered.

SQL> alter system set job_queue_processes=0;

System altered.

SQL> alter system set aq_tm_processes=0;

System altered.

SQL> alter database open;

Database altered.

SQL> alter database character set ZHS16GBK;
alter database character set ZHS16GBK
*
ERROR at line 1:
ORA-12712: new character set must be a superset of old character set

使用internal_use强制转换。
SQL> alter database character set internal_use ZHS16GBK;

Database altered.

SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup;
ORACLE instance started.

Total System Global Area  281018368 bytes
Fixed Size		    2020160 bytes
Variable Size		   96472256 bytes
Database Buffers	  176160768 bytes
Redo Buffers		    6365184 bytes
Database mounted.
Database opened.


参考资料:
http://www.cnblogs.com/kakafra/archive/2012/11/17/2774992.html
http://blog.163.com/magicc_love/blog/static/185853662201211139390563/