搞懂oracle字符集

合集下载

搞懂oracle字符集

搞懂oracle字符集

搞懂oracle字符集作为一个ORACLE DBA,在工作中会经常处理由于字符集产生的一些问题。

但是当真正想写一些这方面的东西时,却突然又没有了头绪。

发了半天呆,还是决定用两个字符集方面的例子作为切入点,倒不失为一个头绪,说不定在实验的过程中,问题就会一个接着一个的浮现出来。

现在,让我们切入正题。

我用的数据库是oracle10.2.0.3,数据库字符集是al32utf8。

客户端就是同一台机器的windows xp.下面是演示的例子:SQL>drop table test purge;Table dropped.SQL>create table test(col1number(1),col2varchar2(10));Table created.--session1设置客户端字符集为zhs16gbk(修改注册表nls_lang项的characterset为zhs16gbk)向表中插入两个中文字符。

SQL>insert into test values(1,'中国');--1为session1的标记1row created.SQL>commit;Commit complete.--session2设置客户端字符集al32utf8(修改注册表nls_lang项的characterset为al32utf8),与数据库字符集相同。

向表中插入两个和session1相同的中文字符。

SQL>insert into test values(2,'中国');--2为session2的标记1row created.SQL>commit;Commit complete.--session1SQL>select*from test;COL1COL2------------------------------2???1中国--session2SQL>select*from test;COL1COL2--------------------2中国1涓 浗从session1和session2的结果中可以看到,相同的字符(注意,我指的是我们看到的,显示为相同的字符),在不同的字符集输入环境下,显示成了乱码。

oracle字符串排序规则

oracle字符串排序规则

oracle字符串排序规则Oracle字符串排序规则在Oracle数据库中,字符串的排序规则是按照字符的Unicode编码值进行排序的。

Unicode编码是一种字符集,它为全球各种语言的字符定义了唯一的编码值。

在Oracle中,字符串排序规则遵循Unicode编码顺序,即根据字符的编码值进行排序。

在Oracle中,字符串排序规则是基于字符的编码值从小到大进行排序的。

这意味着在排序过程中,先出现在Unicode编码表中的字符会排在前面,后出现在编码表中的字符会排在后面。

例如,字母"A"的Unicode编码值是65,字母"B"的Unicode编码值是66,所以在排序时,"A"会排在"B"的前面。

除了字母外,数字和特殊字符也遵循相同的排序规则。

数字的排序是基于其对应的Unicode编码值进行的,数字0的编码值是48,数字1的编码值是49,以此类推。

特殊字符如空格、逗号、句号等也有对应的编码值,它们的排序顺序也是按照Unicode编码值从小到大排序。

在Oracle中,字符串排序规则是大小写敏感的。

这意味着大写字母会排在小写字母的前面。

例如,字符串"Apple"会排在字符串"banana"的前面,因为字母"A"的编码值小于字母"b"的编码值。

如果想要忽略大小写进行排序,可以使用特殊的排序函数进行处理。

在Oracle中还可以根据需要定制字符串的排序规则。

可以使用COLLATE子句来指定排序规则,如COLLATE BINARY表示使用二进制排序规则,COLLATE NOCASE表示不区分大小写进行排序等。

这些定制的排序规则可以满足不同场景下的排序需求。

总结起来,Oracle字符串排序规则是基于字符的Unicode编码值进行排序的。

排序顺序是根据字符在Unicode编码表中的先后顺序来确定的,同时大小写敏感。

Oracle字符集详解

Oracle字符集详解

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为每一个字符提供唯一的编码。

ORACLE数据库DBA专题-字符集

ORACLE数据库DBA专题-字符集

一、字符集基本知识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官方站点:Unicode编码方案主要有三个实施标准:UTF-8,USC-2,UTF-16。

orcle字符集系统介绍及设置

orcle字符集系统介绍及设置

Oracle全球化支持:字符集系统介绍及服务器端、客户端设置1. 字符集与编码常识字符集:人们根据需要把某些字符收集到一处,并赋以名称,于是便有了某某字符集。

例如:ASCII:ASCII字符集:包含大小写英文、阿拉伯数字、标点,以及一些不可见的控制符共128个。

ASCII编码:使用7位表示一个字符。

编码范围是[0-127](即Hex[00-7F]),其中[0-31](Hex[00-1F])部分以及127(Hex7F)是控制符,其余的都是些可见字符。

GB2312:GB2312字符集:ASCII字符集+7000左右汉字字符。

GB2312编码:兼容ASCII编码。

对字节进行判断,如值<=127,则意义等同于ASCII编码;如值>127,则它需要跟其后的另一个字节合并表示一个字符。

其理论汉字编码空间为128X256,超过3万个字符。

GBK:GBK字符集:GB2312字符集+20000左右汉字字符。

GBK编码:兼容GB2312编码。

利用了GB2312编码闲置的编码空间。

GB18030:GB18030字符集:GBK字符集+若干汉字+若干少数民族字符,为目前国内最新的字符集。

GB18030编码:兼容GBK编码。

继续利用GBK编码闲置的编码空间,对于超出编码空间的则采用4个字节表示。

BIG5:BIG5字符集:ASCII字符集+13000左右汉字(繁体)。

BIG编码:兼容ASCII编码。

其编码模式类似于GB2312.UNICODE:(UNICODE一词在日常使用中显得宽泛、混乱,在不同的语境中可以是以下意思之一。

)UNICODE标准:由一些组织提出的一套标准,对人类文字的显示、编码等进行了一系列的规定。

UNICODE字符集:目前最新版的UNICODE字符集中已经包含各种语言的超过10万的字符。

UNICODE编码:(狭义的UNICODE编码可能指UCS-2,也可能指UTF-16;广义的UNICODE 编码可以指包括以下四种在内的若干种对UNICODE标准的编码实现。

oracle字符集详细说明

oracle字符集详细说明

一、什么是oracle字符集Oracle字符集是一个字节数据的解释的符号集合,有大小之分,有相互的包容关系。

ORACLE 支持国家语言的体系结构允许你使用本地化语言来存储,处理,检索数据。

它使数据库工具,错误消息,排序次序,日期,时间,货币,数字,和日历自动适应本地化语言和平台。

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

它的格式如下: NLS_LANG = language_territory.charset它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。

其中:Language 指定服务器消息的语言,territory 指定服务器的日期和数字格式,charset 指定字符集。

如:AMERICAN _ AMERICA. ZHS16GBK从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。

所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。

二.查看数据库字符集这涉及三方面的字符集,一是oracel server端的字符集;二是oracle client端的字符集;三是dmp文件的字符集。

在做数据导入的时候,需要这三个字符集都一致才能正确导入。

1、查询oracle server端的字符集有很多种方法可以查出oracle server端的字符集,比较直观的查询方法是以下这种: SQL> select userenv('language') from dual;结果类似如下:AMERICAN _ AMERICA. ZHS16GBK2、如何查询dmp文件的字符集用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主机上):catexp.dmp |od -x|head -1|awk '{print $2 $3}'|cut -c 3-6然后用上述SQL也可以得到它对应的字符集。

oracle字符集小结

oracle字符集小结

一:影响oracle数据库字符集最重要的参数是NLS_LANG参数它的格式如下:NLS_LANG = language_territory.charset它有三个组成部分(语言、地域和字符集),每个成分控制了NLS子集的特性。

其中:Language 指定服务器消息的语言,territory 指定服务器的日期和数字格式,charset 指定字符集。

如:AMERICAN _ AMERICA.ZHS16GBK从NLS_LANG的组成我们可以看出,真正影响数据库字符集的其实是第三部分。

所以两个数据库之间的字符集只要第三部分一样就可以相互导入导出数据,前面影响的只是提示信息是中文还是英文。

在做数据导入的时候,涉及三方面的字符集,一是oracel server端的字符集;二是oracle client端的字符集;三是dmp文件的字符集。

需要这三个字符集都一致才能正确导入。

二:查询相关字符集1.查看数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。

查看数据库可用字符集参数设置SELECT * FROM v$nls_valid_values;或者col nls_charset_id for 9999col nls_charset_name for a30col hex_id for a20selectnls_charset_id(value) nls_charset_id,value nls_charset_name,to_char(nls_charset_id(value),'xxxx') hex_idfrom v$nls_valid_valueswhere parameter = 'CHARACTERSET'order by nls_charset_id(value)2.如何查询dmp文件的字符集用oracle的exp工具导出的dmp文件也包含了字符集信息,dmp文件的第2和第3个字节记录了dmp文件的字符集。

oracle字符集

oracle字符集
很明显,iso8859-1编码表示的字符范围很窄,无法表示中文字符。
但是,由于是单字节编码,和计算机最基础的表示单位一致,所以很多时候,仍旧使用iso8859-1编码来表示。
而且在很多协议上,默认使用该编码。
UCS:
通用字符集(Universal Character Set,UCS)是由ISO制定的ISO 10646(或称ISO/IEC 10646)标准所定义的字符编码方式,采用4字节编码。
二、有哪些字符集?
ASCII:
American Standard Code for Information Interchange,美国信息交换标准码。
目前计算机中用得最广泛的字符集及其编码,由美国国家标准局(ANSI)制定。
它已被国际标准化组织(ISO)定为国际标准,称为ISO 646标准。
一、什么是字符集?什么是编码?
字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等。
一组抽象字符的集合就是字符集(Charset)。
字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集。
一组有共同特征的字符也可以组成字符集,比如繁体汉字字符集、日文汉字字符集。
偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1。
ISO 8859-1:
ISO 8859,全称ISO/IEC 8859,是国际标准化组织(ISO)及国际电工委员会(IEC)联合制定的一系列8位字符集的标准,现时定义了15个字符集。
ASCII收录了空格及94个“可印刷字符”,足以给英语使用。
UCS包含了已知语言的所有字符。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

搞懂oracle字符集作为一个ORACLE DBA,在工作中会经常处理由于字符集产生的一些问题。

但是当真正想写一些这方面的东西时,却突然又没有了头绪。

发了半天呆,还是决定用两个字符集方面的例子作为切入点,倒不失为一个头绪,说不定在实验的过程中,问题就会一个接着一个的浮现出来。

现在,让我们切入正题。

我用的数据库是oracle10.2.0.3,数据库字符集是al32utf8。

客户端就是同一台机器的windows xp.下面是演示的例子:SQL>drop table test purge;Table dropped.SQL>create table test(col1number(1),col2varchar2(10));Table created.--session1设置客户端字符集为zhs16gbk(修改注册表nls_lang项的characterset为zhs16gbk)向表中插入两个中文字符。

SQL>insert into test values(1,'中国');--1为session1的标记1row created.SQL>commit;Commit complete.--session2设置客户端字符集al32utf8(修改注册表nls_lang项的characterset为al32utf8),与数据库字符集相同。

向表中插入两个和session1相同的中文字符。

SQL>insert into test values(2,'中国');--2为session2的标记1row created.SQL>commit;Commit complete.--session1SQL>select*from test;COL1COL2------------------------------2???1中国--session2SQL>select*from test;COL1COL2--------------------2中国1涓 浗从session1和session2的结果中可以看到,相同的字符(注意,我指的是我们看到的,显示为相同的字符),在不同的字符集输入环境下,显示成了乱码。

在zhs16gbk字符集的客户端,我们看到了utf8字符集客户端输入的相同的中文变成了乱码-->col1=2的col2字段在utf8字符集客户端,我们看到zhs16gbk字符集的客户端输入的中文变成了另外的字符-->col1=1的col2字段从这个例子里,我们好像感觉到出了什么问题,也可能会联想起现实环境中出现的乱码问题。

问题似乎有了思路,ok,让我们继续把实验做下去:--session1(或者session2,在这里无所谓)SQL>select col1,dump(col2,1016)from test;COL1----------DUMP(COL2,1016)--------------------------------------------------------------------------------2Typ=1Len=4CharacterSet=AL32UTF8:d6,d0,b9,fa1Typ=1Len=6CharacterSet=AL32UTF8:e4,b8,ad,e5,9b,bd我们使用了dump函数,结果看起来很明显了,两个完全相同的字符,在不同的字符集环境下,在数据库中存储成了不同的编码。

对于ZHS16GBK的字符集客户端输入的字符"中国",AL32UTF8使用了3个字节来分别存储一个字符,即:中--e4,b8,ad国--e5,9b,bd我们也可以分别对这个字符进行验证:--session1SQL>select dump('中',1016)from dual;DUMP('中',16)--------------------------------------------Typ=96Len=3CharacterSet=AL32UTF8:e4,b8,ad--字符“中”,和上面直接从数据库中读取存储的字符编码一致。

SQL>select dump('国',1016)from dual;DUMP('国',16)--------------------------------------------Typ=96Len=3CharacterSet=AL32UTF8:e5,9b,bd--字符“国”,和上面直接从数据库中读取存储的字符编码一致。

如果使用session2直接对着两个字符进行测试,一样会得到相同的结果(笔者已经做过测试,这里为了避免冗长,删掉了).让我们重新来理一下思路,并提出几个问题:1:为什么显示为相同的字符,存储到数据库中却变成了不同的编码?2:我们在向数据库中插入数据的时候,oracle究竟做了些什么?3:操作系统字符集,客户端字符集,数据库字符集究竟是什么关系?带着这些疑惑,让我们接着做实验,所有的疑团和猜测都会在试验中得以验证。

我的思路是,先取得测试环境的相关参数。

1:windows字符集(codepage)我们使用chcp命令来获得windows使用的字符集c:\chcp活动的代码页:936通过oracle的官方文档阅读,我们可以将它等同于ZHS16GBK字符集(在安装oracle 时,oracle会找到安装平台的字符集,并默认将对应的字符集设置成与它相同,在这里,数据库默认的字符集本身应该是ZHS16GBK,但我强制将它修改为AL32UTF8)。

所以现在我们可以认为,我们使用的操作系统是ZHS16GBk字符集,那么我们在这个环境下输入的字符(也可以说是显示的字符,用的就是这个字符集的编码)。

让我们继续讨论问题。

我们现在要讨论一下客户端字符集究竟是用来做什么的。

我们知道,很多字符集都有自己的编码方式,换句话说,相同的字符,在不同的字符集里对应的编码可能是不一样的。

客户端的字符集就是为了让数据库知道我们传递过去的字符是属于那种字符集,以便于oracle在存储字符时做相应的编码映射。

拿上面的例子来说:比如字符"中国"在ZHS16GBK字符集中,它的编码是:d6,d0,b9,fa在AL32UTF8字符集中,它的编码是:e4,b8,ad,e5,9b,bd让我们看看例子中两个session输入的相同字符在数据库中存储对应的编码:SQL>select col1,dump(col2,1016)from t1;COL1----------DUMP(COL2,1016)--------------------------------------------------------------------------------2Typ=1Len=4CharacterSet=AL32UTF8:d6,d0,b9,fa1Typ=1Len=6CharacterSet=AL32UTF8:e4,b8,ad,e5,9b,bd对于session1,我们设置的客户端字符集为zhs16gbk。

当我们和数据库建立session后,数据库将认为这个客户端以zhs16gbk字符集编码的方式向数据库发送字符,因为数据库的字符集是al32utf8,所以字符要以这个字符集的编码来存储,此时oracle就会做一个字符编码转换,也就是将字符集zhs16gbk中编码为d6,d0,b9,fa的字符编码映射成字符集为al32utf8编码为e4,b8,ad,e5,9b,bd,在字符集al32utf8的编码里,e4,b8,ad,e5,9b,bd对应的字符为"中国".对于session2,我们设置的客户端字符集为al32utf8。

当我们和数据库建立session后,数据库看到客户端的字符集和数据库的字符集一致,此时oracle将不会再对字符作转换,因为它认为两边的字符编码是一致的。

而此时,我们欺骗了数据库,尽管我们将客户端字符集设置为和数据库一致,但是其实我们使用的是zhs16gbk字符集编码(因为此时windows使用的就是这个字符编码),对于字符"中国",zhs16gbk字符集里对应的编码为d6,d0,b9,fa。

此时,oracle不加理会的直接将这个编码保存到了数据库中。

当我们分别将这两个字符dump出来的时候,就得到下面这样的结果。

SQL>select col1,dump(col2,1016)from test;COL1----------DUMP(COL2,1016)--------------------------------------------------------------------------------2Typ=1Len=4CharacterSet=AL32UTF8:d6,d0,b9,fa1Typ=1Len=6CharacterSet=AL32UTF8:e4,b8,ad,e5,9b,bd下面我们就进入到了我们最关心的地方,乱码,让我们继续我们的试验。

--session1SQL>SQL>insert into t1values('中国',1);1row created.SQL>commit;Commit complete.SQL>select*from t1;COL COL2----------------------中国1???2--session2SQL>insert into t1values('中国',2);1row created.SQL>commit;Commit complete.SQL>select*from t1;COL COL2----------------涓 浗1中国2session1,我们看到session2输入的字符"中国"变成了乱码"???",session2,我们看到session1输入的字符"中国"变成了另外的字符"涓 浗",下面我们来分析一下这中间数据库,客户端和操作系统都发生了那些事情。

上面已经讨论了:session1输入的字符"中国"在数据库中存储的字符编码为”e4,b8,ad,e5,9b,bd".session2输入的字符"中国"在数据库中存储的字符编码为”d6,d0,b9,fa".当session1开始查询时,oracle从表中取出这两个字符,并按照字符集al32utf8和字符集zhs16gbk的编码映射表,将它的转换成zhs16gbk字符编码,对于编码“e4,b8,ad,e5,9b,bd”,它对应的zhs16gbk的字符编码为"d6,d0,b9,fa",这个编码对应的字符为”中国“,所以我们看到了这个字符正常显示出来了,而对于字符集al32utf8字符编码“d6,d0,b9,fa”,由于我们用于显示字符的windows环境使用的是zhs16gbk字符集,而在zhs16gbk字符集里面并没有对应这个编码的字符或者属于无法显示的符号,于是使用了"?"这样的字符来替换,这就是为什么我们看到session2输入的字符变成了这样的乱码。

相关文档
最新文档