中文字符unicode查询oracleZHS16GBK的数据库导⼊到字符集为AL32UTF8的数据库
(转载+⾃⼰经验总结)
字符集⼦集向其超集转换是可⾏的,如此例 ZHS16GBK转换为AL32UTF8。
导出使⽤的字符集将会记录在导出⽂件中,当⽂件导⼊时,将会检查导出时使⽤的字符集设置,如果这个字符集不同于导⼊客户端的
NLS_LANG
设置,字符集将根据导⼊客户端NLS_LANG设置进⾏转换,如果必要,在数据插⼊数据库之前会进⾏进⼀步转换。
通常在导出时最好把客户端字符集设置得和数据库端相同,这样可以避免在导出时发⽣不必要的数据转换,导出⽂件将和数据库具有相同的字符集。
即使将来会把导出⽂件导⼊到不同字符集的数据库中,这样做也可以把转换延缓⾄导⼊时刻。
当进⾏数据导⼊时,主要存在以下两种情况:
1.源数据库和⽬标数据库具有相同字符集设置
这时,只需要设置NLS_LANG等于数据库字符集即可导⼊(前提是,导出使⽤的是和源数据库相同字符集,即三者相同)
2.源数据库和⽬标数据库字符集不同
如果我们导出时候使⽤的NLS_LANG是和源数据库相同的字符集,那么导⼊时就可以设置客户端NLS_LANG等于导出时使⽤的字符集,这样转换只发⽣在数据库端,⽽且只发⽣⼀次。
例如:
如果进⾏从ZHS16GBK到UTF8的转换
1)使⽤NLS_LANG=AMERICAN_AMERICA.ZHS16GBK导出数据库。
这时创建的导出⽂件包含ZHS16GBK的数据
2)导⼊时使⽤NLS_LANG=AMERICAN_AMERICA.ZHS16GBK
这时转换仅发⽣在insert数据到UTF8的数据库中。
含有汉字的固定字符由ZHS16GBK数据库导⼊到AL32UTF8的数据库
此⽂章是对于上⼀个实验的补充,上⼀次实验仅仅考虑的 varchar2 的情况。这次考虑到对于char类型的含有中⽂数据的情况。
对于英⽂:
对英⽂,在al32utf8中仍然和zhs16gbk⼀样⽤1个字节表⽰,因此导⼊固定长度英⽂字符数据时不会出错。
对于中⽂:
例如在字符集为zhs16gbk 数据库中创建表时指定字段 val char(15),该字段含有数据 ‘阿⾥云计算公司’在字符集为zhs16gbk 数据库中占⽤14个字
节,⽽在字符集为al32utf8 数据库中占⽤21个字节⼤于 char(15)所指定的长度15.此时导⼊数据就会失败。
对于英⽂字符可以实现由zhs16gbk 到 al32utf8的转换。
解释:⽤UTF-8,UNICODE的2字节字符⽤变长个(1-3个字节)表⽰:
1. 对英⽂,仍然和ASCII⼀样⽤1个字节表⽰,这个字节的值⼩于128(\x80);
2. 扩展的ASCII字符(主要是西欧),第⼀字节⽤C2 - DF之间的范围,双字节表⽰。
3.对其他语⾔,⽐如亚洲语系,还有各种特殊符号,使⽤3个字节表⽰;
因此,在应⽤中程序处理过程中所有字符都是16位(双字节),但在存取转换成字节流时使⽤UTF-8格式转换,对于英⽂字符来说和原来⽤ASCII⽅式存取
时相⽐⼤⼩仍然是⼀样的,⽽对中⽂来说和原来的GB2312编码⽅式相⽐,⼤⼩为:(3字节/2字节)=1.5倍,这也是下⾯导⼊数据失败的原因。
总结
1.当源端字符编码为ZHS16GBK,⽬标端编码为AL32UTF8,客户端随便为其中的⼀种编码,迁移数据不会出现乱码,但是会出现列长度不够现象。反过来不⾏,因为utf8中的部分字符转换到gbk中肯定会不⽀持
2.设置了源端客户端编码,仅仅是导出来的dmp⽂件头部有编码字符标⽰不⼀样,存储数据还是按照服务端存储
3.打破神话,exp/imp导⼊要不乱码,导出和导⼊的客户端编码要⼀致
原因分析,解决建议
在导⼊过程中,最多会发⽣三次编码转换:
1、执⾏exp时,数据库中数据的编码会转换为导出客户端编码
2、执⾏imp时,dmp⽂件的编码转换为导⼊客户端编码
3、导⼊客户端编码转换为⽬标端数据库的数据库编码
在exp/imp操作的过程中,经常出现乱码的原因就是编码的相互转换的过程中出现了丢失或者相互不能转换导致。要解决这个问题,最好的办法就是通过NLS_LANG的灵活设置,减少编码转换的次数(如果相邻的转换操作编码⼀致,那么不会发⽣编码转换,如试验中的
ZHS16GBK编码测试,就没有转换发⽣),或者使得相互的转换能够兼容,可以最⼤程度的减少乱码的出现。
如果已经有了exp导出的dmp⽂件,然后在导⼊的过程中,出现乱码,⼀般的处理建议是nls_lang的编码设置和dmp⽂件的⼀致,让转换发⽣在导⼊客户端和数据库服务器间(要求:编码可以相互转换)
个⼈总结(⾮转载)
恢复备份执⾏(imp)时将客户端设置字符集和⽬标数据库字符集编码格式⼀致
(建议源数据库字符集、客户端、⽬标数据库字符集三者保持⼀致)
1)查看数据库字符集设置
sql--select userenv(‘language’)from dual; oracle中查询的字符集USERENV('LANGUAGE')
我⾃⼰的服务器⽤的是zhs16gbk 中⽂字符集
2)客户端操作系统字符--查询--配置
(1) cmd-chcp 查询指定代码页。下表列出了所有⽀持的代码页及其国家(地区)或者语⾔:
代码页国家(地区)或语⾔
936 中国 - 简体中⽂(GBk)
Windows XP、Windows7、WIN10、WIN sever 2008 R2 操作系统⾃带的都是GBK字符集(含2万余汉字)
936即为中⽂GBK字符集
(2 )查看注册表-win+r--regedit
(3)将客户端添加环境变量。
设置环境变量名NLS_LANG
变量值为SIMPLIFIED CHINESE_CHINA.ZHS16GBK (⼀定重启电脑才⽣效)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论