开发者社区> 小麦苗> 正文

Oracle字符集的简单图解,中文乱码解决

简介: Oracle字符集的简单图解,中文乱码解决 经常碰到SQLPLUS展现乱码的问题,字符集和相关的定义都有说明但是很少有能把这些关系说的很简单易懂的。
+关注继续查看
Oracle字符集的简单图解,中文乱码解决

经常碰到SQLPLUS展现乱码的问题,字符集和相关的定义都有说明但是很少有能把这些关系说的很简单易懂的。

在此之前我们需要搞清楚三个概念,操作系统字符集,客户端字符集,Oracle字符集:

操作系统字符集:对应的参数是LANG,这个参数应该是Oracle数据库的超集,如果操作系统不支持,那么我们的数据就会乱码。这里的操作系统指的是客户端的操作系统。服务器端的操作系统不会影响数据的存取。

数据库字符集:NLS_CHARACTERSET,可以在nls_database_parameters中查看当前数据库的字符集,安装数据库的时候选择,一般不修改,不过在新的字符集是现有字符集的严格超集的情况下可以改,其他情况下修改可能导致数据库异常。例如将UTF8字符集修改为AL32UTF8

关于子集超集的映射关系,见如下Oracle官网的文档的Binary Subset-Superset Pairs

http://docs.oracle.com/database/121/NLSPG/applocaledata.htm#NLSPG591 

客户端字符集:对应的参数是NLS_LANG,如果客户端未设置,此时则取的是安装时数据库的默认参数

为了帮助理解,我画了一张图如下,图中标红部分如果一致表示数据的存储方式一致,即如果LANG、NLS_LANG、NLS_CHARACTERSET的编码是一致的如UTF8,那么数据的传输过程中不会异常,字符乱码只是显示问题。


1、操作系统字符集

linux下首先locale 查看字符集


[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@oddpc ~]$ locale  
  2. LANG=en_US.UTF-8  
  3. LC_CTYPE="en_US.UTF-8"  
  4. LC_NUMERIC="en_US.UTF-8"  
  5. LC_TIME="en_US.UTF-8"  
  6. LC_COLLATE="en_US.UTF-8"  
  7. LC_MONETARY="en_US.UTF-8"  
  8. LC_MESSAGES="en_US.UTF-8"  
  9. LC_PAPER="en_US.UTF-8"  
  10. LC_NAME="en_US.UTF-8"  
  11. LC_ADDRESS="en_US.UTF-8"  
  12. LC_TELEPHONE="en_US.UTF-8"  
  13. LC_MEASUREMENT="en_US.UTF-8"  
  14. LC_IDENTIFICATION="en_US.UTF-8"  
  15. LC_ALL=  
  16. [oracle@oddpc ~]$ echo $LANG  
  17. en_US.UTF-8  

2、该主机并未安装中文支持包,设置LANG后可以效果如下,显然无路如何调整NLS_LANG在这台机器上都无法展现中文



[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@evenpc ~]$ export LANG=zh_CN.utf8  
  2. [oracle@evenpc ~]$ date  
  3. 2016? 10? 13? ??? 15:17:01 CST  

3、安装中文支持包,使用yum -y groupinstall chinese-support 可以安装中文支持包,安装过程略过,安装完毕后可以正常显示中文



[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@oddpc ~]$ export LANG=zh_CN.utf8  
  2. [oracle@oddpc ~]$ date  
  3. 2016年 10月 13日 星期四 15:14:19 CST  


4、接下来就是展现测试,我安装了两个数据库实例PROD1和PROD5,PROD1 的字符集是WE8MSWIN1252,PROD5的字符集是AL32UTF8

默认情况下NLS_LANG是空的,此时NLS_LANG取默认安装时的值,PROD1是AMRICAN,PROD5是SIMPLIFIED CHINESE

[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@oddpc ~]$ echo $NLS_LANG  
  2. [oracle@oddpc ~]$   

[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. SQL> show parameter lang          
  2.   
  3. NAME                                 TYPE        VALUE  
  4. ------------------------------------ ----------- ------------------------------  
  5. nls_date_language                    string  
  6. nls_language                         string      AMERICAN  
[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. SQL> select sysdate from dual;  
  2.   
  3. SYSDATE  
  4. ---------  
  5. 13-OCT-16  



			


PROD5


[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. SQL> show parameter lang    
  2.   
  3. NAME                                 TYPE        VALUE  
  4. ------------------------------------ ----------- ------------------------------  
  5. nls_date_language                    string  
  6. nls_language                         string      SIMPLIFIED CHINESE  
[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. SQL> select sysdate from dual;  
  2.   
  3. SYSDATE  
  4. ----------  
  5. 13-10?-16  
5、PROD5 发生乱码,PROD1英文正常,设置下NLS_LANG参数


PROD1 的结果如下,可以看到提示信息已经变成中文,但是由于字符集非UTF8中文字符存入后将乱码


[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@oddpc ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"  
  2. [oracle@oddpc ~]$ sqlplus / as sysdba  
  3.   
  4. SQL*Plus: Release 11.2.0.3.0 Production on 星期四 10月 13 15:42:46 2016  
  5.   
  6. Copyright (c) 1982, 2011, Oracle.  All rights reserved.  
  7.   
  8.   
  9. 连接到:   
  10. Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production  
  11. With the Partitioning, OLAP, Data Mining and Real Application Testing options<pre name="code" class="sql">SQL> show parameter lang  </pre <>
  12.   
  13. NAME                                 TYPE                              VALUE  
  14. ------------------------------------ --------------------------------- ------------------------------  
  15. nls_date_language                    string                            SIMPLIFIED CHINESE  
  16. nls_language                         string                            SIMPLIFIED CHINESE  
  17. SQL> show parameter db_name  
  18.   
  19. NAME                                 TYPE                              VALUE  
  20. ------------------------------------ --------------------------------- ------------------------------  
  21. db_name                              string                            PROD1  
  22. SQL> show parameter lang  
  23.   
  24. NAME                                 TYPE                              VALUE  
  25. ------------------------------------ --------------------------------- ------------------------------  
  26. nls_date_language                    string                            SIMPLIFIED CHINESE  
  27. nls_language                         string                            SIMPLIFIED CHINESE  
  28. SQL> select sysdate from dual;  
  29.   
  30. SYSDATE  
  31. ------------  
  32. 13-10? -16  
[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. SQL> select * from nls_database_parameters;  
  2.   
  3. PARAMETER                                VALUE  
  4. ---------------------------------------- ----------------------------------------  
  5. NLS_LANGUAGE                             AMERICAN  
  6. NLS_TERRITORY                            AMERICA  
  7. NLS_CURRENCY                             $  
  8. NLS_ISO_CURRENCY                         AMERICA  
  9. NLS_NUMERIC_CHARACTERS                   .,  
  10. NLS_CHARACTERSET                         WE8MSWIN1252  
  11. NLS_CALENDAR                             GREGORIAN  
  12. NLS_DATE_FORMAT                          DD-MON-RR  
  13. NLS_DATE_LANGUAGE                        AMERICAN  
  14. NLS_SORT                                 BINARY  
  15. NLS_TIME_FORMAT                          HH.MI.SSXFF AM  
  16.   
  17. PARAMETER                                VALUE  
  18. ---------------------------------------- ----------------------------------------  
  19. NLS_TIMESTAMP_FORMAT                     DD-MON-RR HH.MI.SSXFF AM  
  20. NLS_TIME_TZ_FORMAT                       HH.MI.SSXFF AM TZR  
  21. NLS_TIMESTAMP_TZ_FORMAT                  DD-MON-RR HH.MI.SSXFF AM TZR  
  22. NLS_DUAL_CURRENCY                        $  
  23. NLS_COMP                                 BINARY  
  24. NLS_LENGTH_SEMANTICS                     BYTE  
  25. NLS_NCHAR_CONV_EXCP                      FALSE  
  26. NLS_NCHAR_CHARACTERSET                   AL16UTF16  
  27. NLS_RDBMS_VERSION                        11.2.0.3.0  
  28.   
  29. 已选择20行。  




			



PROD5的结果如下,此时PROD5显示正常
[sql] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. [oracle@oddpc ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.UTF8"  
  2. [oracle@oddpc ~]$ sqlplus / as sysdba  
  3. SQL*Plus: Release 11.2.0.3.0 Production on 星期四 10月 13 15:46:36 2016  
  4.   
  5. Copyright (c) 1982, 2011, Oracle.  All rights reserved.  
  6.   
  7.   
  8. 连接到:   
  9. Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production  
  10. With the Partitioning, OLAP, Data Mining and Real Application Testing options  
  11. SQL> show parameter db_name  
  12.   
  13. NAME                                 TYPE                              VALUE  
  14. ------------------------------------ --------------------------------- ------------------------------  
  15. db_name                              string                            PROD5  
  16. SQL> select sysdate from dual;  
  17.   
  18. SYSDATE  
  19. ------------  
  20. 13-10月-16  
  21.   
  22. SQL> show parameter lang  
  23.   
  24. NAME                                 TYPE                              VALUE  
  25. ------------------------------------ --------------------------------- ------------------------------  
  26. nls_date_language                    string                            SIMPLIFIED CHINESE  
  27. nls_language                         string                            SIMPLIFIED CHINESE<pre name</pre ="code" class="sql">SQL> select * from nls_database_parameters;  
  28.   
  29. PARAMETER                                VALUE  
  30. ---------------------------------------- ----------------------------------------  
  31. NLS_LANGUAGE                             AMERICAN  
  32. NLS_TERRITORY                            AMERICA  
  33. NLS_CURRENCY                             $  
  34. NLS_ISO_CURRENCY                         AMERICA  
  35. NLS_NUMERIC_CHARACTERS                   .,  
  36. NLS_CHARACTERSET                         AL32UTF8  
  37. NLS_CALENDAR                             GREGORIAN  
  38. NLS_DATE_FORMAT                          DD-MON-RR  
  39. NLS_DATE_LANGUAGE                        AMERICAN  
  40. NLS_SORT                                 BINARY  
  41. NLS_TIME_FORMAT                          HH.MI.SSXFF AM  
  42.   
  43. PARAMETER                                VALUE  
  44. ---------------------------------------- ----------------------------------------  
  45. NLS_TIMESTAMP_FORMAT                     DD-MON-RR HH.MI.SSXFF AM  
  46. NLS_TIME_TZ_FORMAT                       HH.MI.SSXFF AM TZR  
  47. NLS_TIMESTAMP_TZ_FORMAT                  DD-MON-RR HH.MI.SSXFF AM TZR  
  48. NLS_DUAL_CURRENCY                        $  
  49. NLS_COMP                                 BINARY  
  50. NLS_LENGTH_SEMANTICS                     BYTE  
  51. NLS_NCHAR_CONV_EXCP                      FALSE  
  52. NLS_NCHAR_CHARACTERSET                   AL16UTF16  
  53. NLS_RDBMS_VERSION                        11.2.0.3.0  
  54.   
  55. 已选择20行。  


总结:通过以上的实验可以看出,客户端展现是否乱码是由NLS_LANG决定,发生中文乱码的情况下,首先查看数据库的NLS_CHARACTERSET是否支持中文存储,如果不支持,无论如何设置均无法正常显示中文。Oracle官方文档上给出了各种语言的编码支持如下。




字符集问题的初步探讨(一)-字符集的基本知识


Oracle全球支持(即Globalization Support)允许我们使用本地语言和格式来存储和检索数据。通过全球支持,Oracle可以支持多种语言及字符集,得以展示数据库的强大魅力。

由于不同语言及字符集的共同存储存在设置上具有一定的复杂性,字符集一度成为普遍困扰大家的一个主要问题。
本文试图就一些常见问题进行探讨,希望可以把一些实际经验共享给大家!

1. 字符集的基本知识

如果从头说起,字符集最早的编码方案来自于与ASCII.
这也是我们最常见的编码方式。该方案起源于1960年代初期,最初是美国国会图书馆制定用来作为美国图书馆界书目交换的共同标准,最后完善成为美国的国家标准ASCII(American Standard Codefor Information Interchange),之后进一步演变成世界性的计算机字符编码标准ISO646(其全名为7-bit coded character set for information interchange)。成为计算机编码方案的基础。

Oracle数据库最早支持的编码方案也就是US7ASCII.
但是我们知道,英文字符一般是以一个字节来存储的,7位的编码方案最多只能代表128个字符;经过扩展的8位的编码方案也只能代表256个字符,这远远不能满足计算机发展的需要,对于亚洲国家复杂的字符存储需要更多的码位,于是各种编码方案随之而生。

为了容纳全世界各种语言的所有字符和符号,解决不同编码之间的兼容和转换问题,1991年元月,10多家公司共同出资,组建Unicode协会,随后Unicode编码产生了。
Unicode协会的口号是: 给每个字符提供了一个唯一的数字,不论是什么平台,不论是什么程序,不论什么语言。
最初Unicode编码使用2-Byte(16bit)来进行编码,但是最多只能容纳65536个字符,仍然不够使用,后来进行了扩充,也就是Unicode3.1标准,增加了额外的补充字符定义,现在Unicode4.0标准已经发布,具体可以参考Unicode官方站点:

www.unicode.org

Unicode编码方案主要有三个实施标准:
UTF-8
USC-2
UTF-16
Oracle从7.2开始支持UTF-8编码,提供Unicode编码支持。

按照各种标准的含义,Oracle推荐,如果你的数据库需要存放不同语言的不同符号和字符,建议使用Unicode编码方案。诚然,Unicode方案可以表示更多的字符,但是由于多位的存储,需要额外的存储空间和网络传输,所以选择最适合的数据库字符集仍然需要慎重考虑。

字符集问题的初步探讨(二)-数据库的字符集

2. 数据库的字符集

 

字符集在创建数据库时指定,在创建后通常不能更改,所以在创建数据库时能否选择一个正确的字符集就显得尤为重要。

在创建数据库时,我们可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。
字符集用来存储:
     CHAR, VARCHAR2, CLOB, LONG等类型数据
     用来标示诸如表名、列名以及PL/SQL变量等
     SQL和PL/SQL程序单元等
国家字符集用以存储:
     NCHAR, NVARCHAR2, NCLOB等类型数据

这些设置在数据库创建时指定,我们可以看一下数据库的创建脚本:













 

 








chr.JPG

 


 



 



 


 

<><><><><><>



     



 











>


>>

 

>>>>>>>>>>>

<>


>

>>>

>

>>




 

 


>

>








>>>>>>



 



<><><>


>



 

>>>>>>>>


>>




















 

>>




>>








>>



nls2.JPG

img_ff0e67fba944b83f71fe1c7bddc72658.jpg

 

 >>>

 

 

 

 








 

 >>>>>>>>>>>>>>>>>>>>>


ch.JPG

 

 >>>>>


 

 >>>>>>>>>>




 

 >>>>

 >

 

 

 

 


 

 



img_e54b8dcf57ec98d4ce9d1fe89c6fef5d.jpg




 

>>>>>

>




>

>
>



 

 



img_aab86d596adc749477fcf0ba9db40b90.jpg


 

 

 

>>>>>>>>>

 





<>


 






>>>>>>>>>

 




 

 











 





    

img_e3029f287d989cd04bd75432ecc1c172.png
DBA笔试面试讲解
欢迎与我联系

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
linux centos 被攻击乱码 将字符编码设置为中文
linux centos mysql 漏洞导致centos 被执行恶意命令
108 0
Oracle 数据库-服务器端字符集查看方法
Oracle 数据库-服务器端字符集查看方法
35 0
Oracle 一个中文汉字 占用几个字节,由Oracle中字符集编码决定
Oracle 一个中文汉字 占用几个字节,要根据Oracle中字符集编码决定 查看oracle server端字符集 select userenv('language') from dual; 如果显示如下,一个汉字占用两个字节 SIMPLIFIED CHINESE_CHINA.
1099 0
Mac mysql 解决中文乱码
Mac mysql 解决中文乱码问题 出现“???”之类的无法识别的乱码 到/etc目录下自己建一个my.cnf文件(需要最高权限,使用sudo su),然后写入内容: [client] default-character-set=utf8 [mysqld] character-set-server=utf8 保存,修改。
1027 0
gdy
转载:Ununtu下中文乱码解决方案
转载: 添加中文字符编码: $sudo vim /var/lib/locales/supported.d/local #添加下面的中文字符集 zh_CN.GBK GBK zh_CN.GB2312 GB2312 zh_CN.
797 0
oracle修改字符集
sqlplus /nolog conn /as sysdba   Oracle 使用时间长了, 新增了许多user 和tablespace. 需要清理一下 对于单个user和tablespace 来说, 可以使用如下命令来完成。
826 0
中文乱码的分析 和 从Eclipse设置启动JVM时的字符集(转)
最近时常碰到中文乱码的问题,eclipse的编码环境设置的都是UTF-8,外部也是以UTF-8的编码进行传参的,但是遇到中文的时候还是因为乱码而产生一系列的错误。在网上查了许多资料,发现这是跟JVM的编码有关系的,JVM默认引用电脑操作系统的编码格式进行编码(大部分中文win xp系统的编码格式是GBK),所以JVM把java编译成class文件的时候会以GBK的方式进行编译。
1003 0
Gedit中文乱码解决
Gedit中文乱码 出自Ubuntu中文 缺省配置下,用 Ubuntu 的文本编辑器(gedit)打开 GB18030/GBK/GB2312 等类型的中文编码文本文件时,将会出现乱码。 出现这种情况的原因是,gedit 使用一个编码匹配列表,只有在这个列表中的编码才会进行匹配,不在这个列表中的编码将显示为乱码。
1765 0
+关注
小麦苗
小麦苗,专注于数据库,Oracle OCM,PostgreSQL PGCM,PostgreSQL ACE,中国PG分会官方认证讲师,PGfans签约作者,PGfans年度MVP;微信公众号: DB宝,个人网站:www.xmmup.com
889
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载