Oracle字符集问题.docx

上传人:b****4 文档编号:5415273 上传时间:2023-05-08 格式:DOCX 页数:11 大小:107.48KB
下载 相关 举报
Oracle字符集问题.docx_第1页
第1页 / 共11页
Oracle字符集问题.docx_第2页
第2页 / 共11页
Oracle字符集问题.docx_第3页
第3页 / 共11页
Oracle字符集问题.docx_第4页
第4页 / 共11页
Oracle字符集问题.docx_第5页
第5页 / 共11页
Oracle字符集问题.docx_第6页
第6页 / 共11页
Oracle字符集问题.docx_第7页
第7页 / 共11页
Oracle字符集问题.docx_第8页
第8页 / 共11页
Oracle字符集问题.docx_第9页
第9页 / 共11页
Oracle字符集问题.docx_第10页
第10页 / 共11页
Oracle字符集问题.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

Oracle字符集问题.docx

《Oracle字符集问题.docx》由会员分享,可在线阅读,更多相关《Oracle字符集问题.docx(11页珍藏版)》请在冰点文库上搜索。

Oracle字符集问题.docx

Oracle字符集问题

Oracle字符集问题

目录

1字符集基本概念4

1.1概述4

1.2字符编码方案4

1.3字符集超集5

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

1.4.1字符集5

1.4.2国家字符集5

1.5客户端字符集(NLS_LANG参数)6

2字符集的查询与修改7

2.1数据库字符集的查询与修改7

2.1.1查看数据库字符集7

2.1.2修改数据库字符集8

2.1.3修改RAC数据库字符集9

2.2客户端字符集的查看与修改9

2.2.1查看客户端字符集9

2.2.2修改客户端字符集10

3乱码问题11

3.1使用客户端sqlplus向数据库存储数据11

3.2导入/导出过程出现乱码原因12

4单字节编码存储中文问题13

1字符集基本概念

1.1概述

Oracle数据库字符集,即Oracle全球化支持(GlobalizationSupport),或即国家语言支持(NLS)。

其作用是用本国语言和格式来存储、处理和检索数据。

利用全球化支持,ORACLE为用户提供自己熟悉的数据库母语环境,诸如日期格式、数字格式和存储序列等。

由于oracle字符集种类多,且在存储、检索、迁移oracle数据时多个环节与字符集的设置密切相关,因此在实际的应用中,数据库开发和管理人员经常会遇到有关oracle字符集方面的问题。

字符集的实质就是按照一定的字符编码方案,对一组特定的符号,分别赋予不同数值编码的集合。

Oracle的字符集命名遵循以下命名规则:

<语言><比特位数><编码>

例如:

ZHS16GBK表示采用GBK编码格式、16位(两个字节)简体中文字符集

1.2字符编码方案

Ø单字节编码

(1)单字节7位字符集,可以定义128个字符,最常用的字符集为US7ASCII

(2)单字节8位字符集,可以定义256个字符,适合于欧洲大部分国家

例如:

WE8ISO8859P1(西欧、8位、ISO标准8859P1编码)

Ø多字节编码

(1)变长多字节编码:

某些字符用一个字节表示,其它字符用两个或多个字符表示,变长多字节编码常用于对亚洲语言的支持,例如日语、汉语、印度语等

例如:

AL32UTF8(其中AL代表ALL,指适用于所有语言)、ZHS16CGB231280

(2)定长多字节编码:

每一个字符都使用固定长度字节的编码方案,目前oracle唯一支持的定长多字节编码是AF16UTF16,也是仅用于国家字符集

(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编码字符集

1.3字符集超集

当一种字符集(字符集A)的编码数值包含所有另一种字符集(字符集B)的编码数值,并且两种字符集相同编码数值代表相同的字符时,则字符集A是字符集B的超级,或称字符集B是字符集A的子集。

几种常见字符集对应关系:

A.CurrentCharset            B.NewCharset(SupersetofA.)

US7ASCII                       WE8ISO8859P1

US7ASCII                       ZHS16CGB231280

US7ASCII                       ZHS16GBK

US7ASCII                       ZHT16BIG5

US7ASCII                       UTF8

US7ASCII                       AL32UTF8 

UTF8                           AL32UTF8(addedinpatchset9.0.1.2)

US7ASCII                       ZHS32GB18030

UTF8                           AL32UTF8

由于US7ASCII是最早的Oracle数据库编码格式,因此有许多字符集是US7ASCII的超集,例如WE8ISO8859P1、ZHS16CGB231280、ZHS16GBK都是US7ASCII的超集。

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

数据库字符集在创建数据库时指定,在创建后通常不能更改。

在创建数据库时,可以指定字符集(CHARACTERSET)和国家字符集(NATIONALCHARACTERSET)。

1.4.1字符集

(1)用来存储CHAR,VARCHAR2,CLOB,LONG等类型数据

(2)用来标示诸如表名、列名以及PL/SQL变量等

(3)用来存储SQL和PL/SQL程序单元等

1.4.2国家字符集

(1)用来存储CHAR,VARCHAR2,CLOB,LONG等类型数据

(2)国家字符集实质上是为oracle选择的附加字符集,主要作用是为了增强oracle的字符处理能力,因为NCHAR数据类型可以提供对亚洲使用定长多字节编码的支持,而数据库字符集则不能。

国家字符集在oracle9i中进行了重新定义,只能在unicode编码中的AF16UTF16和UTF8中选择,默认值是AF16UTF16

1.5客户端字符集(NLS_LANG参数)

客户端字符集定义了客户端字符数据的编码方式,任何发自或发往客户端的字符数据均使用客户端定义的字符集编码,客户端可以看作是能与数据库直接连接的各种应用,例如sqlplus,exp/imp等。

客户端字符集是通过设置NLS_LANG参数来设定的。

NLS_LANG参数格式

NLS_LANG=language_territory.Clientcharacterset

Language:

显示oracle消息,校验,日期命名

Territory:

指定默认日期、数字、货币等格式

Clientcharacterset:

指定客户端将使用的字符集

例如:

NLS_LANG=AMERICAN_AMERICA.US7ASCII

AMERICAN是语言,AMERICA是地区,US7ASCII是客户端字符集

2字符集的查询与修改

2.1数据库字符集的查询与修改

一旦数据库创建后,数据库的字符集理论上讲是不能改变的。

因此,在设计和安装之初考虑使用哪一种字符集十分重要。

根据Oracle的官方说明,字符集的转换是从子集到超集受支持,反之不行。

如果两种字符集之间根本没有子集和超集的关系,那么字符集的转换是不受oracle支持的。

对数据库server而言,错误的修改字符集将会导致很多不可测的后果,可能会严重影响数据库的正常运行,所以在修改之前一定要确认两种字符集是否存在子集和超集的关系。

一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。

特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。

2.1.1查看数据库字符集

使用如下命令查看数据库字符集:

selectuserenv('language')fromdual;

或者通过视图查询:

SQL>select*fromnls_database_parameters;

PARAMETERVALUE

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

NLS_LANGUAGEAMERICAN

NLS_TERRITORYAMERICA

NLS_CURRENCY$

NLS_ISO_CURRENCYAMERICA

NLS_NUMERIC_CHARACTERS.,

NLS_CHARACTERSETWE8ISO8859P1

NLS_CALENDARGREGORIAN

NLS_DATE_FORMATDD-MON-RR

NLS_DATE_LANGUAGEAMERICAN

NLS_SORTBINARY

NLS_TIME_FORMATHH.MI.SSXFFAM

NLS_TIMESTAMP_FORMATDD-MON-RRHH.MI.SSXFFAM

NLS_TIME_TZ_FORMATHH.MI.SSXFFAMTZR

NLS_TIMESTAMP_TZ_FORMATDD-MON-RRHH.MI.SSXFFAMTZR

NLS_DUAL_CURRENCY$

NLS_COMPBINARY

NLS_LENGTH_SEMANTICSBYTE

NLS_NCHAR_CONV_EXCPFALSE

NLS_NCHAR_CHARACTERSETAL16UTF16

NLS_RDBMS_VERSION10.2.0.1.0

查询结果中NLS_CHARACTERSET表示字符集,NLS_NCHAR_CHARACTERSET表示国家字符集

2.1.2修改数据库字符集

上文说过,oracle的字符集有互相的包容关系。

如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失。

在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。

在Oracle8之前,可以用直接修改数据字典表props$来改变数据库的字符集。

但Oracle8之后,至少有三张系统表记录了数据库字符集的信息,只改props$表并不完全,可能引起严重的后果。

正确的修改方法如下:

若此时数据库服务器已启动,则先执行SHUTDOWNIMMEDIATE命令关闭数据库服务器,然后执行以下命令:

STARTUPMOUNT;

ALTERSYSTEMENABLERESTRICTEDSESSION;

ALTERSYSTEMSETJOB_QUEUE_PROCESSES=0;

ALTERSYSTEMSETAQ_TM_PROCESSES=0;

ALTERDATABASEOPEN;

ALTERDATABASECHARACTERSETZHS16GBK;

ALTERDATABASEnationalCHARACTERSETZHS16GBK;

SHUTDOWNIMMEDIATE;

STARTUP;

如果上述命令失败,使用如下命令:

ALTERDATABASECHARACTERSETINTERNAL_USEZHS16GBK;

SHUTDOWNIMMEDIATE;

STARTUP;

如果修改后的数据库字符集不是当前字符集的一个超集,后果可能是数据丢失和数据错误。

为了确保数据的完整性,修改字符集前一定要进行export/import导出/导入工作。

在使用ALTERDATABASE[NATIONAL]CHARACTERSET命令修改数据库字符集前,对数据库进行完整的备份是十分必要的,因为这个命令导致的结果是无法通过回滚来恢复的。

2.1.3修改RAC数据库字符集

停止一个节点的实例,在另一个节点执行

altersystemsetcluster_database=falsescope=spfile;

按上述修改单实例环境修改字符集

altersystemsetcluster_database=truescope=spfile;

shutdownimmediate;

验证

2.2客户端字符集的查看与修改

2.2.1查看客户端字符集

在Unix或linux平台下,查看环境变量NLS_LANG

echo$NLS_LANG

在Windows平台下,就是注册表里面相应OracleHome的NLS_LANG,也可以在命令行里用:

setNLS_LANG

2.2.2修改客户端字符集

Unix或Linux环境下

exportNLS_LANG="simplifiedchinese"_china.zhs16gbk

Windows环境下,修改注册表

HKEY_LOCAL_MACHINE---SOFTWARE---ORACLE—HOME0

或者直接在系统设置的环境变量里修改或添加:

3乱码问题

oracle在数据存储、迁移过程中经常发生字符乱码问题,归根到底是由于字符集使用不当引起。

下面以使用客户端sqlplus向数据库插入数据和导入/导出(EXP/IMP)过程为例,说明乱码产生的原因。

3.1使用客户端sqlplus向数据库存储数据

这个过程存在3个字符集设置

(1)客户端应用字符集

(2)客户端NLS_LANG参数设置

(3)服务器端数据库字符集(CharacterSet)设置

客户端应用sqlplus中能够显示什么样的字符取决于客户端操作系统语言环境(客户端应用字符集),但在应用中录入这些字符后,这些字符能否在数据库中正常存储,还与另外两个字符集设置紧密相关,其中客户端NLS_LANG参数主要用于字符数据传输过程中的转换判断。

常见的乱码大致有两种情形:

A、汉字变成问号“?

当从字符集A转换成字符集B时,如果转换字符之间不存在对应关系,NLS_LANG使用替代字符“?

”替代无法映射的字符

B、汉字变成未知字符(虽然有些是汉字,但与原字符含义不同)

转换存在对应关系,但字符集A中的字符编码与字符集B中的字符编码代表不同含义

乱码产生是由于几个字符集之间转换不匹配造成,分以下几种情况:

A、服务器端数据库字符集与客户端应用字符集相同,与客户端NLS_LANG参数设置不同如果客户端NLS_LANG字符集是其它两种字符集的子集,转换过程将出现乱码。

解决方法:

将三种字符集设置成同一字符集,或NLS_LANG字符集是其它两种字符集的超集。

B、服务器端数据库字符集与客户端NLS_LANG参数设置相同,与客户端应用字符集不同如果客户端应用字符集是其它两种字符集的超集时,转换过程将出现乱码。

C、客户端应用字符集、客户端NLS_LANG参数设置、服务器端数据库字符集互不相同此种情况较为复杂,但三种字符集之间只要有不能转换的字符,则必产生乱码。

3.2导入/导出过程出现乱码原因

导入导出存在四个字符集设置

(1)源数据库字符集

(2)EXP过程中NLS_LANG参数

(3)IMP过程中NLS_LANG参数

(4)目标数据库字符集

出现乱码原因

a、当源数据库字符集不等于EXP过程中NLS_LANG参数,且源数据库字符集是EXP过程中NLS_LANG的子集,才能保证导出文件正确,其他情况则导出文件字符乱码

b、EXP过程中NLS_LANG字符集不等于IMP过程中NLS_LANG字符集,且EXP过程中NLS_LANG字符集是IMP过程中NLS_LANG字符集的子级,才能保证第一次转换正常,否则第一次转换中出现乱码。

c、如果第一次转换正常,IMP过程中NLS_LANG字符集是目标数据库字符集的子集或相同,才能保证第二次转换正常,否则则第二次转换中出现乱码

4单字节编码存储中文问题

由于历史的原因,早期的oracle没有中文字符集(如oracle6、oracle7、oracle7.1),但有的用户从那时起就使用数据库了,并用US7ASCII字符集存储了中文,或是有的用户在创建数据库时,不考虑清楚,随意选择一个默认的字符集,如WE8ISO8859P1或US7ASCII,而这两个字符集都没有汉字编码,虽然有些时候选用这种字符集好象也能正常使用,但用这种字符集存储汉字信息从原则上说就是错误的,它会给数据库的使用与维护带来一系列的麻烦。

正常情况下,要将汉字存入数据库,数据库字符集必须支持中文,而将数据库字符集设置为US7ASCII等单字节字符集是不合适的。

US7ASCII字符集只定义了128个符号,并不支持汉字。

另外,如果在SQL*PLUS中能够输入中文,操作系统缺省应该是支持中文的,但如果在NLS_LANG中的字符集设置为US7ASCII,显然也是不正确的,它没有反映客户端的实际情况。

但在实际应用中汉字显示却是正确的,这主要是因为Oracle检查数据库与客户端的字符集设置是同样的,那么数据在客户与数据库之间的存取过程中将不发生任何转换,但是这实际上导致了数据库标识的字符集与实际存入的内容是不相符的。

而在SELECT的过程中,Oracle同样检查发现数据库与客户端的字符集设置是相同的,所以它也将存入的内容原封不动地传送到客户端,而客户端操作系统识别出这是汉字编码所以能够正确显示。

在这个例子中,数据库与客户端都没有设置成中文字符集,但却能正常显示中文,从应用的角度看好象没问题。

然而这里面却存在着极大的隐患,比如在应用length或substr等字符串函数时,就可能得到意外的结果。

对于早期使用US7ASCII字符集数据库的数据迁移到oracle8i/9i中(使用zhs16gbk),由于原始数据已经按照US7ASCII格式存储,对于这种情况,可以通过使用Oracle8i的导出工具,设置导出字符集为US7ASCII,导出后使用UltraEdit等工具打开dmp文件,修改第二、三字符,修改0001为0354,这样就可以将US7ASCII字符集的数据正确导入到ZHS16GBK的数据库中。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2