■ 遼寧 彭碩
某公司正在使用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)應用程序使用它確定要加載的本地化信息?!笨梢姡琹ocales.dat文件是客戶端程序的語言環境和字符集配置文件,通過對它進行修改,應當可以修正中文亂碼的問題。
該文件中,依服務器端操作系統平臺的不同,將配置分成了不同的部分。其格式為:
[PLATFORM]
locale=vendor_locale,syb_language,syb_charset
提示:請在修改前對locales.dat文件進行備份。
例如,某Sybase ASE運行于Windows Server操作系統上??蛻舳说膌ocales.dat文件原配置如圖2所示。
其中最后一行中的“default”,即為針對該平臺的默認語言和字符集配置。我們對它進行修改即可。修改后的配置如圖3所示。
在Linux平臺上,為管理操作系統的語言環境,可能會存在“$LANG”變量。該變量對于運行在Linux平臺上的Sybase ASE同樣具有意義。(在其他操作系統平臺上亦可能存在“LANG”變量,需要注意識別。)
例 如,某Sybase ASE運行于RHEL 6操作系統上,RHEL 6系統具有變量“$LANG=en_US.UTF-8”??蛻舳说膌ocales.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 '
如使用iSQL等工具連接數據庫,會得到如圖7所示錯誤消息。
該錯誤消息指出,無法在客戶端的“cp936”和服務器的“cp850”字符集之間進行轉換。但在本案例中,中文字符在數據庫中已使用雙字節格式存儲(cp936字符集與之兼容),不進行任何字符集轉換操作,恰恰是我們所期望的結果。