首页 > 技术文章 > Oracle - 简单理解字符集

atuotuo 2017-08-24 09:56 原文

起因

今天使用SoapUI来模拟第三方的程序进行测试。

简单来说,流程是我们的程序从SoapUI里面获取数据,然后将数据插入数据库从数据库。

SoapUI的脚本来自于第三方,里面包含当地的字符编码,当数据插入到数据库之后,显示出来的内容变成了乱码。

 

分析&解决问题

经过与第三方的交流后,发现数据在第三方自己的Oracle数据库里面显示是没有问题的。于是推测问题是我们的oracle数据库里面字符编码设置的问题。

首先查询字符集

select userenv('language') from dual;

 

然后,将我们的字符集从原先的 SIMPLIFIED CHINESE_CHINA.WE8MSWIN1252 修改为 AL32UTF8 , 问题解决 :)

 

----- 以下部分简单说明 oracle字符集 (转)-----

 

一、什么是Oracle字符集

 

Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。

 

 

 

影响Oracle数据库字符集最重要的参数是NLS_LANG参数。

 

它的格式如下: NLS_LANG = language_territory.charset

 

它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。 其中:

 

Language: 指定服务器消息的语言, 影响提示信息是中文还是英文

 

Territory: 指定服务器的日期和数字格式,

 

Charset:  指定字符集。

 

如:AMERICAN _ AMERICA. ZHS16GBK

 

从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分

 

 

 

 

 

二.字符集的相关知识:

 

2.1 字符集    

实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。Oracle数据库最早支持的编码方案是US7ASCII。    Oracle的字符集命名遵循以下命名规则:    <Language><bit size><encoding>
    即: <语言><比特位数><编码>
    比如: ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集 

 

2.2 字符编码方案

2.2.1 单字节编码    

(1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII
(2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家
             例如:WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)

 

 

 

2.2.2 多字节编码


    (1)变长多字节编码
    某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,   例如日语、汉语、印地语等
    例如:AL32UTF8(其中AL代表ALL,指适用于所有语言)、zhs16cgb231280
    (2)定长多字节编码
    每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集

 

 

2.2.3 unicode编码   

Unicode是一个涵盖了目前全世界使用的所有已知字符的单一编码方案,也就是说Unicode为每一个字符提供唯一的编码。UTF-16是unicode的16位编码方式,是一种定长多字节编码,用2个字节表示一个unicode字符,AF16UTF16是UTF-16编码字符集。
UTF-8是unicode的8位编码方式,是一种变长多字节编码,这种编码可以用1、2、3个字节表示一个unicode字符,AL32UTF8,UTF8、UTFE是UTF-8编码字符集 
  

2.3 字符集超级

当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。
Oracle8i和oracle9i官方文档资料中备有子集-超级对照表(subset-superset pairs),例如:WE8ISO8859P1是WE8MSWIN1252的子集。由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。 

 

2.4 数据库字符集(oracle服务器端字符集)


数据库字符集在创建数据库时指定,在创建后通常不能更改。在创建数据库时,可以指定字符集(CHARACTER SET)和国家字符集(NATIONAL CHARACTER SET)。

 

2.4.1字符集

 (1)用来存储CHAR, VARCHAR2, CLOB, LONG等类型数据
 (2)用来标示诸如表名、列名以及PL/SQL变量等
 (3)用来存储SQL和PL/SQL程序单元等

  

2.4.2国家字符集:

 (1)用以存储NCHAR, NVARCHAR2, NCLOB等类型数据
 (2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16 

 

2.4.3查询字符集参数


可以查询以下数据字典或视图查看字符集设置情况    nls_database_parameters、props$、v$nls_parameters
查询结果中NLS_CHARACTERSET表示字符集,NLS_NCHAR_CHARACTERSET表示国家字符集 

 

2.4.4修改数据库字符集


按照上文所说,数据库字符集在创建后原则上不能更改。不过有2种方法可行: 

 

1. 如果需要修改字符集,通常需要导出数据库数据,重建数据库,再导入数据库数据的方式来转换。

 

2. 通过ALTER DATABASE CHARACTER SET语句修改字符集,但创建数据库后修改字符集是有限制的,只有新的字符集是当前字符集的超集时才能修改数据库字符集,例如UTF8是US7ASCII的超集,修改数据库字符集可使用ALTER DATABASE CHARACTER SET UTF8。 

 

 

PS. 我这里就是采用的第一种方法来修改字符集的,感谢大家的收看,欢迎交流于点赞!!


参考链接:

http://www.cnblogs.com/rootq/articles/2049324.html

 

 

 

 

推荐阅读