全面认识Oracle数据库字符集 |
什么是Oracle字符集 Oracle字符集是一个字节数据解释的符号 集中,有大小之分,有 彼此的 包容关系 。 Oracle 支撑国家语言的体系 构造同意你 使用当地化语言来存储, 解决,检索数据 。它使数据库工具, 舛误 信息,排序 秩序,日期, 工夫,货币,数字和日历自动适 该当地化语言和平台 。 影响oracle数据库字符集最主要的参数是NLS_LANG参数 。它的 格局如下: NLS_LANG = language_territory.charset 它有三个构成 部分(语言、地区和字符集),每个成分操纵了NLS子集的 特点 。其中: Language指定服务器 信息的语言,territory指定服务器的日期和数字 格局,charset指定字符集 。如:AMERICAN _ AMERICA. ZHS16GBK 。 从NLS_LANG的构成我们 可以看出,真正影响数据库字符集的其实是第三 部分 。所以两个数据库中间的字符集 惟独第三 部分一样就 可以 彼此导入导出数据,前面影响的只不过 揭示信息是中文还是英文 。 如何 查问Oracle的字符集 众多人都碰到过由于字符集不同而使数据导入失败的状况 。这 波及三方面的字符集,一是Oracel server端的字符集,二是oracle client端的字符集;三是dmp文件的字符集 。在做数据导入的时候,需求这三个字符集都 统一 威力正确导入 。 1、 查问Oracle Server端的字符集 有众多种 步骤 可以查出oracle server端的字符集, 比较直观的 查问 步骤是以下这种: SQL>select userenv(‘language’) from dual; 后果 类似如下:AMERICAN _ AMERICA. ZHS16GBK. 2、如何 查问dmp文件的字符集 用Oracle的exp工具导出的dmp文件也包括了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集 。假如dmp文件不大, 比方惟独几M或几十M, 可以用UltraEdit 打开(16进制 模式),看第2第3个字节的内容,如0354, 而后用以下SQL查出它对应的字符集: SQL> select nls_charset_name(to_number('0354','xxxx')) from dual; ZHS16GBK 假如dmp文件很大, 比方有2G以上(这也是最常见的状况),用文本编辑器 打开很慢或者 彻底打不开, 可以用以下命令(在unix主机上): cat exp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6 而后用上述SQL也 可以得到它对应的字符集 。 3、 查问Oracle client端的字符集 这个 比较 方便 。在Windows平台下,便是注册表里面相应OracleHome的NLS_LANG.还 可以在Dos窗口里面自己设置, 比方: set nls_lang=AMERICAN_AMERICA.ZHS16GBK 这样就只影响这个窗口里面的环境变量 。在Unix平台下,便是环境变量NLS_LANG. $echo $NLS_LANG AMERICAN_AMERICA.ZHS16GBK 假如 审查的 后果发现Server端与Client端字符集不 统一,请统一 批改为同Server端 雷同的字符集 。 批改Oracle的字符集 上文说过,oracle的字符集有 彼此的 包容关系 。 如us7ascii便是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据 迷失 。在全部的字符集中utf8应该是最大,由于它基于unicode,双字节 保留字符(也 因此在存储空间上占用更多) 。 一旦数据库 缔造后,数据库的字符集 实际上讲是不能转变的 。 因此,在设计和安装之初考量 使用哪一种字符集非常主要 。依据Oracle的官方 注明,字符集的转换是从子集到超集受 支撑,反之不行 。假如两种字符集中间 根本没有子集和超集的关系,那么字符集的转换是不受oracle 支撑的 。对数据库server而言, 舛误的 批改字符集将会招致众多不可测的 后果,可能会严峻影响数据库的 畸形运行,所以在 批改之前 定然要确认两种字符集是不是存在子集和超集的关系 。普通来说,除非万不得已,我们不 提议 批改oracle数据库server端的字符集 。特殊 注明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280中间不存在子集和超集关系, 因此 实际上讲这两种字符集中间的 彼此转换不受 支撑 。 批改Server端字符集(不 提议 使用): 在Oracle 8之前, 可以用直接 批改数据字典表props$来转变数据库的字符集 。但Oracle8之后,至少有三张系统表记录了数据库字符集的信息,只改props$表并不 彻底,可能引起严峻的 后果 。正确的 批改 步骤如下: $sqlplus /nolog SQL>conn / as sysdba; 若此时数据库服务器已启动,则先执行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 批改dmp文件字符集: 上文说过,dmp文件的第2第3字节记录了字符集信息, 因此直接 批改dmp文件的第2第3字节的内容就 可以‘骗’过oracle的 审查 。这样做 实际上也仅是从子集到超集 可以 批改,但众多状况下在没有子集和超集关系的状况下也 可以 批改,我们常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK 根本都 可以改 。由于改的只不过dmp文件,所以影响不大 。 具体的 批改 步骤 比较多,最 方便的便是直接用UltraEdit 批改dmp文件的第2和第3个字节 。 比方想将dmp文件的字符集改为ZHS16GBK, 可以用以下SQL查出该种字符集对应的16进制代码: SQL> select to_char(nls_charset_id('ZHS16GBK'), 'xxxx') from dual; 0354 而后将dmp文件的2、3字节 批改为0354即可 。 假如dmp文件很大,用ue 无奈 打开,就需求用程序的 步骤了 。网上有人用java存储过程写了转换的程序(用java存储过程的 好处是通用性教好,缺陷是 比较麻烦) 。我在Windows下测试通过 。但要求Oracle数据库 定然要安装JVM选项 。 |