筆者軟件編制采用的工具是Borland公司的 Delphi,數據庫采用微軟的Access數據庫。因為涉及下級單位較多,而且因新增項目原因,入庫單位數量還在不斷變化,為此專門編寫了一個單位維護模塊,如圖1所示。
單位維護是一個基礎性的數據維護工作,標準化和準確性要求都很高。為確保錄入信息準確,特別增加了一個單位校驗功能。校驗原理和代碼實現都很簡單,設計思路是將單位表中的所有記錄遍歷一遍,逐一取出單位名稱,通過執行SQL語句進行快速比對,如果有2個或以上記錄,說明單位名稱有重復,生成列表清單供管理人員修訂。就是這么一個簡單的校驗功能卻出現了異常狀況(如圖2),很明顯,列表清單中名稱并不相同的兩個單位被系統認為是兩個相同的單位,赫然顯示在篩查結果中。

圖1 單位維護

圖2 校驗結果
問題究竟出在哪里呢?經筆者初步判斷,問題可能來自三個方面,一是程序代碼編制問題;二是數據本身問題;三是數據庫系統兼容問題。順著這個思路,筆者首先查看了校驗功能的主要代碼片斷,如下所示:


從邏輯和語句上看都沒有問題。再看看數據,筆者發現,所有重復單位中都出現有一個字符“〇”,如圖2中所示的“第二〇一醫院”和“第二一〇醫院”。經查,“〇”這個字符的機器內碼為“A996”,是一個特殊漢字,可以在Word中通過“插入→日期和時間”得到(如圖3)。
筆者推測,如果去掉這個字符“〇”,就變成了“第二一醫院”,這時系統不就誤認為是同一個單位了嗎?也就是說,系統在進行SQL比對時,是將這個“〇”字符過濾掉后進行的,所以就查到了兩個相同的單位。為了驗證這一猜測,筆者進入Access軟件,利用其自帶的SQL查詢工具,輸入“第二〇一醫院”、“第二一〇醫院”和“第二一醫院”三個取值條件進行SQL驗證,果不其然,得到的結果均相同(如圖 4)。

圖3 插入“〇”字符

圖4 SQL測試一
與此同時,筆者又對與“〇”(A996)字符外形非常類似的幾個字符,如“○”(A1F0)、“O”(A3CF)、“О”(A7B0)等字符進行了深入研究,發現SQL語句的執行結果均正常。這充分說明,“〇”(A996)字符是一個特殊字符,當遇到如“〇”這種特殊字符時,SQL執行會出現異常,需要我們特別加以注意。
找到了問題所在,如何解決這一帶有普遍性而又極具隱蔽性的問題呢?最先想到的也是最簡單直接的辦法,就是將這個特殊字符換掉,比如,可以用阿拉伯數字“0”代替,或者用上文所述的任意一個與它外形相似的字符替代都可以。顯然,這種方案是可行的,也是有效的,但似乎還不是最完美的解決方案。正如前文所述,隨著管理項目數量不斷增加,單位數量也在不斷變化之中,管理人員極有可能再次將這個特殊字符錄入系統。所以,筆者認為,若要從根本上解決這一問題,最終需要從程序端入手,將系統變得更為“健壯”,而不是從用戶端著手,對其使用進行限制,這樣,既能避免“故障”發生,又不會影響用戶的使用習慣。
正是基于以上考慮,筆者重新對代碼進行了分析,可以看到,矛盾的焦點主要在以下SQL語句:

而此語句的關鍵之處在于使用了SQL的“=”關鍵字,筆者想,能不能使用其他替代的SQL語句實現相同的功能呢?答案是肯定的,SQL語句的“Like”關鍵字就可以完美替代。一般的,我們在實現模糊查詢時,會經常使用SQL的“Like”關鍵字,當條件值足夠具體時,其功能與“=”沒有本質區別。
于是,筆者又進入Access軟件,通過SQL查詢工具進行測試(如圖5)。
結果很明顯,SQL關鍵字“Like”的執行效果與關鍵字“=”的執行效果完全相同,還是無法解決特殊字符帶來的困惑。筆者還是不甘心,懷疑可能是Access數據庫的兼容性問題,隨后又在SQL Server數據庫中進行求證,得到的結果仍然相同。到此時,真的是有些灰心了,因為這似乎可以下結論說,Access或者SQL Server這類數據庫對類似“〇”(A996)的特殊字符束手無策了!
冷靜下來后,通過進一步分析突然發現,前面我們所用的SQL查詢工具都是系統自帶的,而自帶的一些輔助工具往往在功能和性能上都會比較弱,所以,僅憑它們的測試結果還不能輕易下定論,還需要采用第三方SQL測試工具進行驗證,或許會有不同的結論呢。

圖5 SQL測試二

圖6 Access查詢分析器

圖7 校驗結果
順著這個思路,使用了一款名為“Access查詢分析器”的第三方SQL工具軟件進行測試。當使用“=”關鍵字進行查詢時,結果和前面一樣,但當用“Like”關鍵字時,得到了我們期望的結果(如圖 6)。
通過以上分析和測試后,立即將程序代碼進行了修改。即,將代碼行:


代碼編譯后運行,所有帶有特殊字符“〇”(A996)的單位名稱數據順利通過校驗,再無異常出現,故障得到圓滿解決,結果如圖7所示。
通過對這個因特殊字符引起的“程序故障”典型案例的分析,從中可以總結出以下一些經驗,一是在程序設計中,測試環節非常重要,它就是一個出“故障”的環節,絕不能因其簡單而忽視或輕視這一環節;二是在故障排除過程中,不能因一時一事的失敗而氣餒,那樣只會半途而廢、功敗垂成,而應鍥而不舍、堅持不懈,冷靜、客觀、全面地分析故障對象,運用一切技術手段,多角度、多層面不斷由表及里,才能直達病灶,取得成功;三是應多從用戶角度出發,多為用戶著想,樹立用戶至上的理念,這樣才能得到最優解決方案。