2022年修改oracle字符集 .pdf
测试的时候,本机oracle 安装采用了 utf8 字符集,而项目的要求是gbk字符集,为了防止以后有不同字符集数据信息导入导出的问题,整理以下文档。修改 oracle 字符集新装了 oracle,装为 AL32UTF8 格式,无奈一个工程导出包是 ZHS16GBK 格式,想了想办法转换,以下是学习一、什么是 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 端的字符集,比较直观的查询方法是以下这种:SQLselect userenv(language)from dual;结果类似如下:AMERICAN _ AMERICA.ZHS16GBK(本机结果 SIMPLIFIED CHINESE_CHINA.AL32UTF8)2、如何查询 dmp文件的字符集名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 4 页 -用 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 平台下,就是注册表里面HKEY_LOCAL_MACHINESOFTWAREORACLEHOME0NLS_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 的官方说明,字符集的转换是从子集到超集受支持,反之不行。如果两种字符集之间根本没有子名师资料总结-精品资料欢迎下载-名师精心整理-第 2 页,共 4 页 -集和超集的关系,那么字符集的转换是不受oracle 支持的。对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。一般来说,除非万不得已,我们不建议修改oracle 数据库 server 端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK 和 ZHS16CGB231280 之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。1、修改 server 端字符集(不建议使用)在 oracle 8 之前,可以用直接修改数据字典表props$来改变数据库的字符集。但 oracle8 之后,至少有三张系统表记录了数据库字符集的信息,只改props$表并不完全,可能引起严重的后果。正确的修改方法如下:$sqlplus/nolog SQLconn/as sysdba;以上方法测试不行,用 scott/tiger登陆 sqlplus然后 connect sys/sys as sysdba,然后输入命令即可若此时数据库服务器已启动,则先执行SHUTDOWN IMMEDIATE命令关闭数据库服务器,然后执行以下命令:SQLSTARTUP MOUNT;SQLALTER SYSTEM ENABLE RESTRICTED SESSION;SQLALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;SQLALTER SYSTEM SET AQ_TM_PROCESSES=0;SQLALTER DATABASE OPEN;SQLALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK;/跳过超子集检测SQLALTER DATABASE national CHARACTER SET INTERNAL ZHS16GBK;这一行不起作用,执行后出错ORA-00933:SQL 命令未正确结束,不过执行上一行命令已经生效,其他文章里未提到本行。SQLSHUTDOWN IMMEDIATE;SQLSTARTUP 2、修改 dmp文件字符集名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 4 页 -上文说过,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选项。有兴趣的朋友可以研究一下程序代码名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 4 页 -