在不同数据库做数据rxlb迁移、同其它系统交换数据等,常常因为字符集708u不同而导致迁移失败或数c1o6据库内数据变成乱码。现在我l0eu将oracle字符集708u相关的一些知识做个简单总5my7结
一、什么是oracle字符集708u
oracle字符集708u是一个字节数据的解释的符号集合,有大小8l74之分,有相互的包容关系。oracle
支持国家语言的体系结构允许你使6he5用本地化语言来存储,〖处〗〖理〗,检索数据。它使数据9162库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适s48z应本地化语言和平台。
影响oracle数据库字f8p7符集最重要的参数是nls_lang参数。它的格g13l式如下:
nls_lang
= language_territory.charset
它有三个组成wt0a部分(语言、地域和字符集708u),每个成分控制oj01了nls子集的特性。其中:
language
指定服务器消息的语言,territory
指定服务器的日期和数字格式,charset 指定字znr1符集。如:american _ america.
zhs16gbk
从nls_lang的组成我们可以看出,真正影6g65响数据库字f8p7符集的mcpj其实是第11s4三部分。所以两个数据库之间的j650字gb62符集只要第三部分一样就可以相互导入导出数据,〖前〗〖面〗〖影〗〖z〗〖5〗〖〗〖〗〖〗〖〗〖〗〖6〗〖h〗〖响〗〖的〗〖只〗〖是〗〖提〗〖示〗〖信〗〖息〗〖是〗〖中〗〖文〗〖还〗〖是〗〖英〗〖文〗〖<〗〖/〗〖s〗〖p〗〖a〗〖n〗〖>〗〖。〗〖<〗〖/〗〖p〗〖>〗〖
〗〖<〗〖p〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖
〗〖<〗〖s〗〖t〗〖r〗〖o〗〖n〗〖g〗〖>〗〖二〗〖、〗〖如〗〖何〗〖查〗〖b〗〖9〗〖〗〖〗〖〗〖〗〖〗〖b〗〖5〗〖询〗〖o〗〖r〗〖a〗〖c〗〖l〗〖e〗〖的〗〖字〗〖符〗〖集〗〖7〗〖〗〖〗〖〗〖〗〖8〗〖u〗〖<〗〖/〗〖s〗〖t〗〖r〗〖o〗〖n〗〖g〗〖>〗〖<〗〖/〗〖p〗〖>〗〖
〗〖<〗〖p〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖&〗〖n〗〖b〗〖s〗〖p〗〖;〗〖<〗〖w〗〖b〗〖r〗〖>〗〖
〗〖很〗〖多〗〖人〗〖都〗〖碰〗〖到〗〖过〗〖因〗〖为〗〖字〗〖符〗〖集〗〖7〗〖〗〖〗〖〗〖〗〖8〗〖u〗〖不〗〖同〗〖而〗〖使〗〖数〗〖据〗〖9〗〖1〗〖〗〖〗〖〗〖〗〖6〗〖2〗〖导〗〖入〗〖失〗〖败〗〖的〗〖情〗〖况〗〖。〗〖这〗〖<〗〖s〗〖p〗〖a〗〖n〗〖 〗〖>〗〖涉〗〖及〗〖三〗〖1〗〖j〗〖〗〖〗〖〗〖〗〖〗〖〗〖v〗〖h〗〖方〗〖面〗〖的〗〖字〗〖符〗〖集〗〖7〗〖〗〖〗〖〗〖〗〖8〗〖u〗〖<〗〖/〗〖s〗〖p〗〖a〗〖n〗〖>〗,一是oracel
server端的字u665符集,二是oracle
client端的字u665符集;三是dmp文件的48kz字符集708u。在做数ge8t据rxlb导入的时候,需要这wr70三个字符集708u都一致才能正确导入。
1、查询oracle server端的字u665符集
有很多种方法可以查出oracle
server端的字u665符集,比较直观的查询方法是以下这种:
sql>select
userenv(‘language’) from dual;
结果类u4mj似如下:american _ america. zhs16gbk
2、如何查b9b5询dmp文件的48kz字符集708u
用oracle的exp工具导出的dmp文件也5079包含了字符集708u信息,〖<〗〖s〗〖p〗〖a〗〖n〗〖 〗〖>〗〖d〗〖m〗〖p〗〖文〗〖件〗〖的〗〖4〗〖8〗〖〗〖〗〖〗〖〗〖k〗〖z〗〖第〗〖2〗〖和〗〖第〗〖3〗〖个〗〖字〗〖节〗〖记〗〖k〗〖z〗〖〗〖〗〖〗〖〗〖〗〖k〗〖7〗〖录〗〖了〗〖d〗〖m〗〖p〗〖文〗〖件〗〖的〗〖4〗〖8〗〖〗〖〗〖〗〖〗〖k〗〖z〗〖字〗〖符〗〖<〗〖/〗〖s〗〖p〗〖a〗〖n〗〖>〗〖集〗〖。〗〖如〗〖果〗〖d〗〖m〗〖p〗〖文〗〖件〗〖不〗〖大〗,比如只有
几m或几十m,可以用1tuawry5ultraedit打开(16进制方式),看第2第3个字节的内容,如0354,然后用lm1n以下sql查出它对应的0n2u字符集708u:
sql> select nls_charset_name(to_number('0354','xxxx'))
from dual; zhs16gbk
如果dmp文件很大,比如有2g以上(这也是最常见的情况),用文本28z2编辑器打开很慢或者完全打不开,可以用1tuawry5以下命令(在unix主机上):
cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6
然后用lm1n上述sql也可以得到它对应的0n2u字符集708u。
3、查询oracle client端的字u665符集
这个比较简单。在windows平台下,就是注g8re册表里面相应oraclehome的nls_lang。还可以在dos窗口里面自己设置,比如:
set
nls_lang=american_america.zhs16gbk
这样就只影响这个窗口里面的环境4z8p变量。
在unix平台下,就是环境变量nls_lang。
$echo
$nls_lang
american_america.zhs16gbk
如果检查的结果发现2h4wserver端与client端字符集708u不一致,请统一修改为同server端相同owvq的字符集708u。
三、修改oracle的字符集708u
上面说过,oracle的字符集708u有互相的包容关系。如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有xjl0数据解释
上的问题,不会有xjl0数据丢失。在所有的字符集708u中utf8应该是最大,因为它基于unicode,双字节205j保存字符(也因此在存储空间上占用更多)。
一旦数据库创0325建后,数据库的字符集708u理论上讲是不能改变的。因此,在设计和安装44p3之初考虑使用哪一种字符集708u十分重6sbw要。根据oracle的官方说明,字符集708u的mcpj转
换是从子集到t61s超集受支持,反之不行。如果两种字j8z8符集之间nf93根本没有子集和超集的8x18关系,那么字符集708u的mcpj转换是不受oracle支持的。对数据库server而
言,错误的修改字0gu1符集将会导致很多不ou09可测的后果,可能会严重影响数据库的正常运行,所以在a494修改之前一定要确认两种字j8z8符集是否存在子集和超集的8x18关系。一般来
说,除非万不得已,我们不建议修改oracle数据库server端的字u665符集。特别说nt77明,〖我〗〖们〗〖最〗〖常〗〖用〗〖的〗〖两〗〖种〗〖字〗〖j〗〖8〗〖〗〖〗〖〗〖〗〖〗〖z〗〖8〗〖符〗〖集〗〖z〗〖h〗〖s〗〖1〗〖6〗〖g〗〖b〗〖k〗〖和〗〖
〗〖z〗〖h〗〖s〗〖1〗〖6〗〖c〗〖g〗〖b〗〖2〗〖3〗〖1〗〖2〗〖8〗〖之〗〖间〗〖不〗〖存〗〖在〗〖子〗〖集〗〖和〗〖超〗〖集〗〖关〗〖系〗,因此理96qv论上讲这两种字j8z8符集之间nf93的相互转换不受支持。
1、修改server端字符集708u(不建议使用)
在oracle
8之前,可以用1tuawry5直接修改数据字典表0008props$来改变数据库的字符集708u。但oracle8之后,至少有三张系统表记录了数据库字f8p7符集的mcpj信息,只改props$表并不完全,可能引起严重的后果。正确的修改方法如下:
$sqlplus
/nolog
sql>conn / as sysdba;
若此时he06数据库服务器已启动,则先执phwe行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
2、修改dmp文件字符集708u
上文说过,dmp文件的48kz第2第3字节记kzk7录了字符集708u信息,因此直接修改dmp文件的48kz第2第3字节的内容就可以‘骗’过oracle的检查u4qw。这样做理论上也仅
是从子集到t61s超集可以2297修改,但很多情况下在没有子集和超集关系的情况下也4v3o可以修改,我们常用的一些字符集708u,如
us7ascii,we8iso8859p1,zhs16cgb231280,〖z〗〖h〗〖s〗〖1〗〖6〗〖g〗〖b〗〖k〗〖基〗〖本〗〖都〗〖可〗〖以〗〖改〗〖1〗〖5〗〖〗〖〗〖〗〖〗〖〗〖m〗〖3〗〖。〗〖因〗〖为〗〖改〗〖的〗〖只〗〖是〗〖d〗〖m〗〖p〗〖文〗〖件〗,所以影响不大。
具体的修改方法比较ul4k多,最简单的就是直接用ultraedit修改dmp文件的48kz第2和第3个字节。比如想将dmp文件的48kz字符集708u改为zhs16gbk,可以用1tuawry5以下sql查出该种字符集708u对应的0n2u16进制代qtyq码:
sql> select to_char(nls_charset_id('zhs16gbk'), 'xxxx') from dual; 0354
然后将dmp文件的48kz2、3字节修改为0354即可。
如果dmp文件很大,用ue无法打开,就需要用程序的方法hxn1了。网上有人用java存储过程写了转换的程序(用java存储过程的好处是通用性教6946好,缺点是
比较麻烦)。我在windows下测试ybbw通过。但要求oracle数据库一定要安装jvm选项。有兴趣的朋友可以研究一下程序代码.
摘自:http://tech.it168.com/oldarticle/2006-08-22/200608221647218_1.shtml