怎样解决Oracle客户端与数据库字符集之间汉字显示问题

更新时间:2023-03-29 11:56:01 阅读量: 建筑文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

oracle客户端与后台数据库字符集问题的完美解决办法

QUESTION&ANSWER

怎样解决Oracle客户端与数据库字符集之间汉字显示

问题

编程疑难问题解答

如果存储汉字,最好选择zhs16gbk字符集,在中文处理和统计方面比较方便。

但是,由于诸多历史原因,企事业单位的很多应用系统都使用基于us7ascii字符集的数据库。近年来,由于引进了基于

1.问题的提出

实际操作Oracle数据库的过程中,想要显示的汉字有时会莫明其妙地变为英文问号或者一些英文乱码。其实,这是因为客户端Oracle字符集“NLS_LANG”设置不同于服务器数据库字符集“CHARACTER_SET”,造成中文字符显示错误。因此,解决汉字显示的问题,最简单的方法就是将数据库的客户端字符集与数据库字符集设置一致。然而,如果存储的汉字出现乱码,问题就非常复杂。本文试从此方面进行Oracle汉字存储的微观分析。首先,简介一下计算机存储字符的基础知识。

(1)英文ASCII编码

zhs16gbk字符集数据库的应用程序,造成数据库客户端字符集

的设置不同,使得汉字显示和存储遇到了上述一开始提到的问题。以下通过实例分析数据库客户端字符集和数据库字符集不同时的汉字存储和显示。

(1)同一客户端需要连接两个字符集的数据库

Oracle官方不赞同使用字符集转换功能,虽然us7ascii是zhs16gbk的子集,也不十分建议子集到超集的升级。所以启动

不同的应用程序之前,要按所连数据库的字符集修改本地客户端的字符集设置。有两个方法:

ASCII是英文AmericanStandardCodeforInformationInter-change的缩写。它是计算机编码方案的基础,是最通用的单字

节编码系统。计算机只能以二进制“0”和“1”代码存储数据,所以ASCII码将每个字符对应一个数值,比如字母A的

1)修改应用程序的初始化设置,程序连接数据库前,自

动执行Oracle客户端字符集设置“setnls_lang=AMERI-

CAN_http://www.77cn.com.cn7ASCII”或者“setnls_lang=SIMPLIFIEDCHINESE_CHINA.ZHS16GBK”。

2)编写.reg注册表文件,程序启动前手动修改客户端字

符集,如图1所示。

ASCII码是65,数值0的ASCII码是48。但是,ASCII码比较

原始,使用一个7位二进制存储,最多只能代表128个字符。其中,第0—32号和第127号是通信和控制字符,比如“回车”、

“NULL”、

“退出”等;第33—126号是94个字符,包

括:第48—57号是0—9十个数字,第65—90号是26个大写英文字母,第97—122号为26个小写英文字母,其余32个字符是一些标点和运算符号。

(2)简体中文GB2312-1980编码

GB2312是中国国家标准的简体中文字符集,基本满足了

汉字的计算机处理需要。GB2312收录简化汉字及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共7445个图形字符。其中包括

6763个汉字,其中一级汉字3755个,二级汉字3008个。GB2312用“分区”存储字符,每区有94个汉字或符号,称作

区位码。01—09区为特殊符号;16—55区为一级汉字,以拼音排序;56—87区为二级汉字,以部首/笔画排序;10—15区和88—94区为空。所以,汉字的总码位共72×94=6768个,其中第5590(D7FAH)—5594(D7FEH)位是5个空值。汉字使用两个8位二进制存储,占用两个字节,区号,

“低位字节”存储位号。

“高位字节”存储“位字节”的存

“区字节”的存储范围是

不过,也可尝试升级数据库的字符集,从根本上避免连接两个字符集的数据库。可用“ALTERDATABASE...”语句修改数据库,但必须是子集到超集的升级。此项操作存在风险,慎重执行。如下步骤:

CMD进入DOS界面。

C:\sqlplus/nolog

SQL>conn/assysdba

SQL>SHUTDOWNIMMEDIATE;SQL>STARTUPMOUNT;

SQL>ALTERSYSTEMENABLERESTRICTEDSES-SION;SQL>ALTERSYSTEMSETJOB_QUEUE_PROCESS-ES=0;

SQL>ALTERSYSTEMSETAQ_TM_PROCESSES=0;SQL>ALTERDATABASEOPEN;

SQL>ALTERDATABASECHARACTERSETZHS16GBK;注:Oracle如果报错提示数据库存在clob字段。

A1H—F7H,即01—87区的区号加上A0H;

储范围是A1H—FEH,即01—94位的位号加上A0H,一个汉字的区号和位号都加上160,就得到了机内码。GB2312字符集的第一个汉字是“啊”,区位码是1601:区号=16、位号=

01,高低字节都加上A0H得到汉字处理编码B0A1H。

2.数据库数据的存储和显示

如果只存储英文,最好采用us7ascii单字节的字符集,高效且节省空间。

2010.9

87

oracle客户端与后台数据库字符集问题的完美解决办法

实用第一智慧密集

从D:\oracle\admin\orachar\bdump\alert_orachar.log文件可以查出哪个表报错。

执行truncatetable表名。升级成功后,再重新建立此表。

集’)。

b)Oracle的dump函数返回参数的存储值。语法:dump(‘参数’,1016),返回参数类型、占用字节数、数据库字符集

设置、存储值的十六进制表示。1010是十进制值表示。

SQL>SHUTDOWNIMMEDIATE;SQL>STARTUP;

(2)数据库客户端的字符集不同于数据库的字符集,如何解决存储汉字的错误。

测试环境:客户端操作系统是WindowsXP简体中文版

c)还原乱码为汉字。汉字ASCII值=汉字编码高位字节×256+低位字节。通过逆运算,将两个乱码字符的ASCII值加上128,即:两个8位二进制字节置回丢失的首位1。chr(前字

符十进制复原值×256+后字符十进制复原值)得到相应的汉字。

sp2,服务器是Windows2003Server简体中文版,数据库及其

客户端都是Oracle9.2.0.1。

d)转换错误的乱码。取得汉字机内码的十进制值,将每

个字节的值减去128,即:首位1变0。chr(单字节值-128)得到相应的字符乱码。

1)数据库的客户端字符集是数据库字符集的子集。①字符集:数据库客户端字符集是us7ascii,数据库字符

集是zhs16gbk。

e)WTZH是zhs16gbk字符集数据库的连接串。

⑥结论:如果发生存储错误,必须全是中文字符,包括:

汉字、中文标点、运算符等,才能利用以上算法还原每个双字节为正确汉字。万一含有英文及其标点符号等单字节编码的字符,就需要复杂的字符串分析,甚至需要汉字库的乱码对照表,通过单、双字节依次比对来筛选乱码,还原汉字。

②测试结果:从客户端保存的汉字出现乱码。

③微观分析:Oracle客户端将汉字传送给服务器前会自动

转换编码,将汉字编码变为ASCII码。由于标准ASCII码不能表示汉字,所以一个汉字被替换为两个ASCII字符。

④例如:汉字“中”的机内码是D6D0H,由于ASCII码

利用一个7位二进制存储,所以转换时造成汉字高低位两个字节的首位缺失。即:高位字节和低位字节同时减去80H,得到了它的国标码:5650H。56H和50H两个字节就是英文V和P的机内码。英文字符集客户端传送给中文字符集数据库的一个汉字就变成了两个单字节字符。汉字GB2312-80字符集的区位码范围是1601D—8794D,区码和位码同时加上20H是汉字的国标码,范围是1001H+2020H—575EH+2020H,即:

2)数据库的客户端字符集是数据库字符集的超集。①字符集:数据库客户端字符集是zhs16gbk,数据库字符

集是us7ascii。

②测试结果:从客户端保存的汉字全变成英文问号。③微观分析:客户端的字符集包括数据库字符集,Oracle

客户端将汉字传送给服务器时找不到相应的对照关系,就会用英文问号代替每一个字符,所以汉字全变成“?”。

④例如:存储“中华人民共和国”,因为英文ASCII码表

找不到对应值,所以保存的全是?号。当然,dump函数传递的汉字参数同样变为?号,如图3所示:

3021H—777EH,对应的ASCII字符就是“0!”—“w~”。因此,

掌握了汉字区位码、国标码和机内码的含义和换算,就有了处理错误编码的技巧和方法。万一客户端录入存储汉字出现如上错误,可以科学计算还原汉字。如图2所示:

⑤图例解释:

a)Oracle的userenv(‘lang’)取得数据库客户端的字符

⑤图例解释:

a)Oracle的convert函数将数据存储从一种编码转换为另

一种编码。语法:convert(‘字符’,‘目标字符集’,‘源字符

集:zhs16gbk。

b)Oracle的userenv(‘language’)取得数据库的字符集:us7ascii。

2010.9

电脑编程技巧与维护

oracle客户端与后台数据库字符集问题的完美解决办法

QUESTION&ANSWER

c)字符集前的语言和地域设置不影响数据的存储和显示。Language代表服务器消息的语言,territory为服务器的日期和

数字格式。

编程疑难问题解答

库的方法简便、高效。但是,假如数据库的客户端和数据库字符集不一致,就会发生备份和恢复错误。为此,编制程序生成并存储GB2310—80的全部6763个汉字,分析数据库中文数据的备份和恢复。

(1)通过C#2005生成区位码范围1601D—8794D的简体汉字,如图6所示。

d)WTUS是us7ascii字符集数据库的连接串。

⑥结论:存储英文等单字节字符没有问题。但是,存储

中文字符的错误无法挽回。

(3)数据库客户端的字符集和数据库的字符集相同,O-

ralce不进行编码转换,存储汉字正确,如图4所示。

核心语句解释:

(4)数据库客户端的字符集不同于数据库的字符集,显示汉字的错误同理于存储汉字,如图5所示。

1)设置C#语言集:EncodingGB=system.Text.Encoding.GetEncoding("GB2312");

2)取得区码后,加上A0H变为机内码:chrBt[0]=(byte)(i/100+160);

3)取得位码后,加上A0H变为机内码:chrBt[1]=(byte)(i%100+160);

4)取得简体汉字:chrCn=GB.GetString(chrBt);

5)如果位码超过94,跳到下区从01开始:if(i.ToString().EndsWith("94"))

{i=i+6;}。计算机的基本存储单位是

一个8位二进制,数值94十六进制为5EH,加上A0H变为机内码是FEH。那95的变形码就是FFH,全1不存储数据。

96—99的变形码是100H—103H,超出一个字节。所以,位码94之后不能存储汉字编码。

(2)数据库客户端的字符集不论与数据库的字符集是否

1)图例解释:

①数据库客户端字符集是zhs16gbk,数据库字符集是us7ascii,将汉字显示为错误的ASCII字符。

②数据库客户端字符集是us7ascii,数据库字符集是zhs16gbk,将汉字显示为?号。

③Oralce的dump()函数得到cnchar字段的机内码一致,

两个数据库内存储的汉字正确。

相同,导出DMP文件的表数据都正确,如图7所示。

1)图例解释:图中文件名命名规则:zh是zhs16gbk,us

是us7ascii。to左侧代表数据库字符集,右侧代表客户端字符集。

2)结论:表数据以二进制编码存储,只要存在表中的汉

字正确,exp备份的结果是一样的。但是,如果数据库客户端和数据库字符集不同,表字段的汉字描述、后台函数过程里的中文都会变成乱码或?号。同理,导入和目标数据库字符集一样的DMP文件,客户端字符集不影响表数据的导入,只是中文描述发生错误。

(3)数据库客户端的字符集和数据库的字符集相同,如何

2)结论:仅显示错误没有问题,按开篇提出的设置客户

端字符集和数据库一样就能正确显示汉字。

3.数据库数据的导出和导入

利用Exp/Imp导出和导入数据是最安全的备份和恢复数据

2010.9

89

oracle客户端与后台数据库字符集问题的完美解决办法

实用第一智慧密集

1.硬件部分

(1)工作原理

该部分主要包括音频信号的发射和接收电路。图1为发射部分原理图,话筒拾取的的音频信号经三极管VT放大后推动红外发射管。由于发射管的发射强度与通过其电流成正比,所以VD1、VD2所发出的红外光,便受到音频信号的调制。为了防止失真,VD1、VD2要设一定的偏置。图2为接收部分原理图。电路采用了一块音频放大集成电路LM386。VD为红外线接收管。当音频信号调制的红外光照射到VD时,在其两部产生一个与音频信号变化规律相同的电信号,经C1耦合至

IC,进行放大。

正确导入不同于目标数据库字符集的DMP文件。

数据库DMP文件的第52和53字节记录了源数据库的字符集,也就是DMP文件的字符集设置。第2和3字节记录了导出时客户端的字符集设置。通过SQL语句:

“select

nls_charset_name(to_number('0001','xxxx')),nls_charset_name(to_number('0354','xxxx'))

fromdual;”得到0001H代表

us7ascii字符集,0354H代表zhs16gbk字符集。

第2和3字节的设置不会影响DMP文件的导入,要导入不同于目标数据库字符集的DMP文件,必须修改第52、53字

(2)元器件选择与制作

A、B间可接废旧耳聋助听器的麦克或直接连入电视机等

节为目标数据库字符集的十六进制值,如图8所示。

总之,所论述的一些观点和测试结果仅限于文中的测试环境。如有偏差,敬请赐教指正。

音源的音频输出端,三极管VT选用8050中功率管,Pcm=

300mw,Icm=500mA,R2的功率要在1/4W以上,VD为红外

线接收管(不要选用光电二极管,以免受干扰影响接收效果),其他元件无要求,通用件即可。焊接完毕后,发射部分只需调节R1使VT的静态电流在30mA左右。接收部分只要安装无误,不需调试即可工作,工作时将CK端连接到声卡的MIC输入端。在不使用无线发射功能时,将音频信号直接接到接收管VD处,并断开电阻R1即可。两只发射管安装时,要考虑其辐射区范围。要使它们的辐射角度有一部分重叠。本转发器的设计接收灵敏度稍低,目的是增加抗干扰能力。经实测,其

(同济大学软件学院天津港信息技术发展有限公司王彤)

怎样用VB编程实现多功能录音装置

该装置可实现无线、有线的录音放音功能。用于无

线监听、电视节目、电话等设备的录音,可方便地构成一款外语听力、口语复读机。

2010.9

电脑编程技巧与维护

本文来源:https://www.bwwdw.com/article/qlyl.html

Top