ORACLE 字符集转换:乱码问题

1.字符集说明

ORACLE数据库字符集包括两部分:数据库字符集和客户端字符集.

查看数据库字符集:

 

SQL> select * from nls_database_parameters a where a.PARAMETER in ('NLS_LANGUAGE','NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET','NLS_TERRITORY');

PARAMETER VALUE

------------------------------ --------------------------------------------------------------------------------

NLS_LANGUAGE AMERICAN

NLS_TERRITORY AMERICA

NLS_CHARACTERSET ZHS16GBK

NLS_NCHAR_CHARACTERSET AL16UTF16

NLS_LANGUAGE:数据库使用的语言,影响 返回消息的语言、日期类型等,影响NLS_DATE_LANGUAGE 和NLS_SORT.

NLS_CHARACTERSET:数据库使用的字符集

NLS_NCHAR_CHARACTERSET:国家字符集

NLS_TERRITORY :数据库的区域,影响NLS_DATE_FORMATE等

 

客户端的字符集

客户端指SQLPLUS等工具,这些工具所在的系统也有自己的字符集。windows下查看字符集:

 

C:\Users\wj>chcp

活动代码页: 936

936代表 简体中文,相当于数据中的zhs16gbk。客户端中字符集设置是在注册表中ORACLEHOME中的NLS_LANG。可以命令台中设置字符集和语言,格式为 set nls_lang= <LANGUAGE>_<TERRITORY>.<CHARACTERSET>,如:

set nls_lang=SIMPLIFIED CHINESE_CHINA.ZHS16GBK,只对当前窗口有效。

注意:实际上并不会改变OS的字符集,只是设置ORACLE的环境变量

 

 

2.数据库与客户端之间的字符集转换的问题

有时候会经常发现乱码。原因就是客户端和数据库之间进行字符集转换,导致字符丢失出现乱码。

如:

服务器的字符集是WB8ISO8859P1,这是个单字节的字符集。

现在设置客户端的字符集:set nls_lang=.ZHS16GBK,然后向表T中加入一行数据

insert into t values('ZHS16GBK','我们');

commit;

再设置客户端的字符集:set nls_lang=. WB8ISO8859P1,然后再向表T中加入一行数据

insert into t values('WB8ISO8859P1','我们');

commit;

 

然后分别设置字符集检查T表:

 

 

发现客户端字符集为WB8ISO8859P1查询时,第一次条件显示乱码,本来是"我们"显示为"靠",第二条显示正常。

客户端字符集为ZHS16GBK时,两条记录都是乱码。

 

来分析下原因.

假设"我们"的ZHS16GBK编码为9922 0034.客户端实际发送的是ZHS16GBK编码.

 

客户端字符集设置为ZHS16GBK时,写到数据库时,由于NLS_LANG和数据库里的不一样,要发生转换,这时将会吧9922 0034 转换为WB8ISO8859P1里的编码,而WB8ISO8859P1没有表示"我们"的编码,会用一个默认的字符代替,假设是034 234,这时保存的字符已经不是"我们"。当查询时,会把034 234 转换到ZHS16GBK,这里显示为"靠".其实就是在ZHS16GBK-> WB8ISO8859P1丢失了字符.

 

客户端字符集设置为WB8ISO8859P1时,写到数据库时,由于NLS_LANG和数据库里的一样,不用发生字符转换,直接把9922 0034存到数据库中(虽然9922 0034在WB8ISO8859P1中不一定是有意义的编码,但是可以这样存储).在查询的时候,也不用发生字符转换,直接把9922 0034 返回给客户端,客户端通过ZHS16GBK解释9922 0034为"我们".

 

参考引用:《韩思捷:教你如何成为10G OCP》

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值