影响oracle数据库字符集的最重要参数是NLS_LANG参数。
其格式如下:NLS_LANG=language_temitory.charset
由三个部分组成(语言,地域和字符集),每个成分控制了NLS子集的特性
Language:指定服务器消息的语言,影响提示消息是中文还是英文
Territory:指定服务器的日期和数字格式
Charrset:指定字符集
例如示例库:
sys@ORCL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK
在这三部分中,真正影响数据库字符集的其实是第三部分。
所以两个数据库之间的字符集只要第三部分一样就可以相互导入和导出,前面
影响的只是提示消息是中文还是英文。
当一种字符集(A)的编码数值包含所有另一种字符集(B)的编码数值,并且这两种
字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超集,或者说B是A的子集。
数据库字符集在创建数据库时指定,在创建后通常不能更改。不过有两种方法可行
a.导出数据库数据,重建数据库,再导入数据库数据
b.通过alter database character set语句修改,这种情况,只有在新的字符集是当前字符集的超集时才可行
例如UTF8是us7ascii的超集,即可用 alter database character set utf8
涉及三方面的字符集
a.oracle server端的字符集
b.oracle client端的字符集
c.dmp文件的字符集
在做数据导入的时候,需要者三者都一致才能正确导入
1.查询oracle server端的字符集
select userenv(;language') from dual;
2.查询dmp文件的字符集
使用exp工具导出的dmp文件包含了字符集信息,dmp文件的第2个和第三个字节记录了dmp文件的字符集
。可以用ultraedit打开,查看地第三个字节的内容,如0354,则就可用以下sql查看dmp的文件字符集
select nls_character_name(to_number('0 3 5 4','xxxx') from dual;
3.查看oracle client端的字符集
windows平台,即为注册表中oracle home的nls_lang参数,可以在dos窗口子集设置
如:set nls_lang=AMERICAN_AMERICA.ZHS16GBK
Unix平台.就是环境变量NLS_LANG
如果客户端和服务端的字符集不一致,统一修改为同server端相同的字符集
在客户端和服务端字符集一致时,才能正确显示数据库肚饿非ASCII字符(否则就会出现乱码等情况)
字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。
以oracle用户登陆UNIX,
#sqlplus “/ as sysdba”
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER SESSION SET SQL_TRACE=TRUE;
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 (INTERNAL_USE) ZHS16GBK;
//如果不使用“INTERNAL_USE”参数,系统会提示出错:
//ERROR at line 1:
//ORA-12712: new character set must be asuperset of old character set
SQL> ALTER SESSION SET SQL_TRACE=FALSE;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;
此时,检查一下数据库的字符集是否更改过来
SQL> select value$ from props$ wherename=’NLS_CHARACTERSET’;
VALUE$
-----------------
ZHS16GBK
最简单的就是直接修改dmp文件第2,3字节的内容就可以骗过oracle的检查。由于只是对dmp
文件的修改,超集子集的影响并不大
比如想将dmp文件的字符集改为ZHS16GBK,可以用以下SQL查出该种字符集对应的16进制代码: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual;
0354
然后将dmp文件的2、3字节修改为0354即可。