APP下载

解决SYBASE数据库中文乱码

2020-04-15辽宁彭硕

网络安全和信息化 2020年4期
关键词:乱码字符客户端

■ 辽宁 彭硕

某公司正在使用BF品牌的ERP系统,其中系统后端数据库为Sybase ASE 12.5.4,运行于中文版Windows Server 2008 R2操作系统上。ERP客户端程序均运行于中文版Windows操作系统上,在ERP客户端程序内显示、录入中文字符均正常。

当在使用Sybase Central v6.0等软件连接数据库时,数据库中存储的(包括用户表中的数据、存储过程和触发器)中文字符在软件内显示为乱码,给数据分析、排错等工作造成不便,如图1所示。

故障成因分析

通过调查,确定实际情况如下:ERP软件厂商在进行部署之初,即将Sybase数据库字符集设置为“cp850”,数据库语言设置为“us_english”。且在长达数年的实际使用中,并未有ERP系统的最终用户反应中文存在乱码的问题。

图1 Sybase Central查询结果中显示乱码

为进一步确定数据库中的中文字符以何种编码形式存储,笔者使用Wireshark软件对Sybase Central的查询过程进行抓包。通过分析数据包的载荷,可发现常见汉字均以双字节形式存储。(受限于测试条件,未能在数据库中找到特别生僻的汉字——即GB18030编码中存在的少量占四字节存储空间的汉字。)例如,“刘”字在数据包中的十六进制形态为“C1F5”,这与现行的三种简体中文编码(GB2312、GBK、GB18030)相对应。

由于在本案例中的Sybase ASE处于生产环境,为避免对ERP系统运行造成影响,或出现不可预知的兼容性问题,因此不可能对Sybase ASE数据库的字符集进行修改。

综上所述,尽管CP850(西欧)字符集并不适合存储中文字符,但其并未改变中文字符的双字节编码结构。通过抓包亦可证实,Sybase Central等软件已经收到了汉字正确的二进制代码,但却无法将其解码为汉字。由此可推断,是这些软件的字符集设置出现了问题。

确定要使用的字符集

在Sybase ASE 12.5.0.3及更高的版本中,共支持4种可显示简体中文的字符集(编 码),分别是EUCGB、CP936、GB18030和UTF8。EUCGB字符集源自GB2312标准,仅支持汉字6000余个;CP936字符集源自GBK标准,支持汉字20000余个,并向下兼容GB2312;GB18030字符集源自同名标准,为我国目前最新的中文编码字符集强制性标准,向下兼容GBK和GB2312。因UTF8的编码规则与前述三种字符集互不兼容,故不在本案例中探讨。

在Windows系统的区域和语言设置中,有一处“非Unicode程序的语言”设置。例如,使用记事本编辑一段中文,在保存时选择“ANSI”编码,再将前述设置调整为“英语(美国)”。重启计算机后,无论是在命令行还是记事本中,均无法正确查看文件中的汉字。尽管文件中的数据没有变(可通过WinHEX验证),但由于字符集设置不同,显示结果也不同。

图2 客户端的locales.dat文件原配置

图3 修改后的配置

图4 客户端的locales.dat文件原配置

在简体中文版本的Windows操作系统上,通过在命令行中输入命令“chcp”,即可得知系统的“中文(中国)”区域设置,对应的页码(字符集)为936(GBK)。因此,在本案例中,笔者选用CP936作为Sybase开放客户端(Open Client)的字符集,以获得更好的兼容性。

修改配置并测试

在Sybase安装目录下的locales子目录中,有一文件名为locales.dat。据官方文档的描述,该文件“以Sybase专有格式提供了特定平台的语言环境信息(locale information)”,“开放客户端(Open Client)应用程序使用它确定要加载的本地化信息。”可见,locales.dat文件是客户端程序的语言环境和字符集配置文件,通过对它进行修改,应当可以修正中文乱码的问题。

该文件中,依服务器端操作系统平台的不同,将配置分成了不同的部分。其格式为:

[PLATFORM]

locale=vendor_locale,syb_language,syb_charset

提示:请在修改前对locales.dat文件进行备份。

例如,某Sybase ASE运行于Windows Server操作系统上。客户端的locales.dat文件原配置如图2所示。

其中最后一行中的“default”,即为针对该平台的默认语言和字符集配置。我们对它进行修改即可。修改后的配置如图3所示。

在Linux平台上,为管理操作系统的语言环境,可能会存在“$LANG”变量。该变量对于运行在Linux平台上的Sybase ASE同样具有意义。(在其他操作系统平台上亦可能存在“LANG”变量,需要注意识别。)

例 如,某Sybase ASE运行于RHEL 6操作系统上,RHEL 6系统具有变量“$LANG=en_US.UTF-8”。客户端的locales.dat文件原配置如图4所示。

这种情况下,直接修改默认值(default)并无效果,需要根据“$LANG”变量的值进行有针对性的修改。修改后的配置如图5所示。

在完成修改后,需重启Sybase Central。而 在当建立“连接”时,点击“选项(Details)”按 钮,在“字符 集(Character Set)”中选 择“cp936”(与locales.dat中的修改相对应),在“语言(Language)”中选择“us_english”(与Sybase ASE安装语言相对应),如图6所示。

对于Sybase ASE 15.0及更高版本的服务器,还需要修改一处配置,以禁用Unicode转换。

对于15.0之前版本的Sybase ASE,此配置默认值为0,无需修改。

图5 根据“$LANG”修改后的配置

图6 Sybase Central v6.0中设置连接

完成上述配置后,再使用Sybase Central浏览数据库中的内容,即可发现中文字符已经可以正常显示了。

同时,在SQL Advantage(或Interactive SQL)、iSQL等工具中使用中文字符进行查询,亦可得到正确的查询结果。

图7 使用iSQL等工具连接数据库出现错误消息

错误信息及其他

在本案例中,Sybase ASE上仅安装了“english”语言。如在连接设置中选择其他语言(如“Chinese”),会得到“Neither language name in login record 'chinese'nor language name in syslogins '' is an official language name on this ASE.Using server-wide default 'us_english' instead.”的错误消息,但并不影响最终的显示效果。

如使用iSQL等工具连接数据库,会得到如图7所示错误消息。

该错误消息指出,无法在客户端的“cp936”和服务器的“cp850”字符集之间进行转换。但在本案例中,中文字符在数据库中已使用双字节格式存储(cp936字符集与之兼容),不进行任何字符集转换操作,恰恰是我们所期望的结果。

猜你喜欢

乱码字符客户端
你的手机安装了多少个客户端
“人民网+客户端”推出数据新闻
——稳就业、惠民生,“数”读十年成绩单
对症下药解决多种乱码难题
论高级用字阶段汉字系统选择字符的几个原则
这些真的不是乱码,是汉字
字符代表几
一种USB接口字符液晶控制器设计
图片轻松变身ASCⅡ艺术画
新华社推出新版客户端 打造移动互联新闻旗舰