筆者軟件編制采用的工具是Borland公司的 Delphi,數(shù)據(jù)庫采用微軟的Access數(shù)據(jù)庫。因為涉及下級單位較多,而且因新增項目原因,入庫單位數(shù)量還在不斷變化,為此專門編寫了一個單位維護模塊,如圖1所示。
單位維護是一個基礎(chǔ)性的數(shù)據(jù)維護工作,標(biāo)準(zhǔn)化和準(zhǔn)確性要求都很高。為確保錄入信息準(zhǔn)確,特別增加了一個單位校驗功能。校驗原理和代碼實現(xiàn)都很簡單,設(shè)計思路是將單位表中的所有記錄遍歷一遍,逐一取出單位名稱,通過執(zhí)行SQL語句進行快速比對,如果有2個或以上記錄,說明單位名稱有重復(fù),生成列表清單供管理人員修訂。就是這么一個簡單的校驗功能卻出現(xiàn)了異常狀況(如圖2),很明顯,列表清單中名稱并不相同的兩個單位被系統(tǒng)認(rèn)為是兩個相同的單位,赫然顯示在篩查結(jié)果中。
圖1 單位維護
圖2 校驗結(jié)果
問題究竟出在哪里呢?經(jīng)筆者初步判斷,問題可能來自三個方面,一是程序代碼編制問題;二是數(shù)據(jù)本身問題;三是數(shù)據(jù)庫系統(tǒng)兼容問題。順著這個思路,筆者首先查看了校驗功能的主要代碼片斷,如下所示:
從邏輯和語句上看都沒有問題。再看看數(shù)據(jù),筆者發(fā)現(xiàn),所有重復(fù)單位中都出現(xiàn)有一個字符“〇”,如圖2中所示的“第二〇一醫(yī)院”和“第二一〇醫(yī)院”。經(jīng)查,“〇”這個字符的機器內(nèi)碼為“A996”,是一個特殊漢字,可以在Word中通過“插入→日期和時間”得到(如圖3)。
筆者推測,如果去掉這個字符“〇”,就變成了“第二一醫(yī)院”,這時系統(tǒng)不就誤認(rèn)為是同一個單位了嗎?也就是說,系統(tǒng)在進行SQL比對時,是將這個“〇”字符過濾掉后進行的,所以就查到了兩個相同的單位。為了驗證這一猜測,筆者進入Access軟件,利用其自帶的SQL查詢工具,輸入“第二〇一醫(yī)院”、“第二一〇醫(yī)院”和“第二一醫(yī)院”三個取值條件進行SQL驗證,果不其然,得到的結(jié)果均相同(如圖 4)。
圖3 插入“〇”字符
圖4 SQL測試一
與此同時,筆者又對與“〇”(A996)字符外形非常類似的幾個字符,如“○”(A1F0)、“O”(A3CF)、“О”(A7B0)等字符進行了深入研究,發(fā)現(xiàn)SQL語句的執(zhí)行結(jié)果均正常。這充分說明,“〇”(A996)字符是一個特殊字符,當(dāng)遇到如“〇”這種特殊字符時,SQL執(zhí)行會出現(xiàn)異常,需要我們特別加以注意。
找到了問題所在,如何解決這一帶有普遍性而又極具隱蔽性的問題呢?最先想到的也是最簡單直接的辦法,就是將這個特殊字符換掉,比如,可以用阿拉伯?dāng)?shù)字“0”代替,或者用上文所述的任意一個與它外形相似的字符替代都可以。顯然,這種方案是可行的,也是有效的,但似乎還不是最完美的解決方案。正如前文所述,隨著管理項目數(shù)量不斷增加,單位數(shù)量也在不斷變化之中,管理人員極有可能再次將這個特殊字符錄入系統(tǒng)。所以,筆者認(rèn)為,若要從根本上解決這一問題,最終需要從程序端入手,將系統(tǒng)變得更為“健壯”,而不是從用戶端著手,對其使用進行限制,這樣,既能避免“故障”發(fā)生,又不會影響用戶的使用習(xí)慣。
正是基于以上考慮,筆者重新對代碼進行了分析,可以看到,矛盾的焦點主要在以下SQL語句:
而此語句的關(guān)鍵之處在于使用了SQL的“=”關(guān)鍵字,筆者想,能不能使用其他替代的SQL語句實現(xiàn)相同的功能呢?答案是肯定的,SQL語句的“Like”關(guān)鍵字就可以完美替代。一般的,我們在實現(xiàn)模糊查詢時,會經(jīng)常使用SQL的“Like”關(guān)鍵字,當(dāng)條件值足夠具體時,其功能與“=”沒有本質(zhì)區(qū)別。
于是,筆者又進入Access軟件,通過SQL查詢工具進行測試(如圖5)。
結(jié)果很明顯,SQL關(guān)鍵字“Like”的執(zhí)行效果與關(guān)鍵字“=”的執(zhí)行效果完全相同,還是無法解決特殊字符帶來的困惑。筆者還是不甘心,懷疑可能是Access數(shù)據(jù)庫的兼容性問題,隨后又在SQL Server數(shù)據(jù)庫中進行求證,得到的結(jié)果仍然相同。到此時,真的是有些灰心了,因為這似乎可以下結(jié)論說,Access或者SQL Server這類數(shù)據(jù)庫對類似“〇”(A996)的特殊字符束手無策了!
冷靜下來后,通過進一步分析突然發(fā)現(xiàn),前面我們所用的SQL查詢工具都是系統(tǒng)自帶的,而自帶的一些輔助工具往往在功能和性能上都會比較弱,所以,僅憑它們的測試結(jié)果還不能輕易下定論,還需要采用第三方SQL測試工具進行驗證,或許會有不同的結(jié)論呢。
圖5 SQL測試二
圖6 Access查詢分析器
圖7 校驗結(jié)果
順著這個思路,使用了一款名為“Access查詢分析器”的第三方SQL工具軟件進行測試。當(dāng)使用“=”關(guān)鍵字進行查詢時,結(jié)果和前面一樣,但當(dāng)用“Like”關(guān)鍵字時,得到了我們期望的結(jié)果(如圖 6)。
通過以上分析和測試后,立即將程序代碼進行了修改。即,將代碼行:
代碼編譯后運行,所有帶有特殊字符“〇”(A996)的單位名稱數(shù)據(jù)順利通過校驗,再無異常出現(xiàn),故障得到圓滿解決,結(jié)果如圖7所示。
通過對這個因特殊字符引起的“程序故障”典型案例的分析,從中可以總結(jié)出以下一些經(jīng)驗,一是在程序設(shè)計中,測試環(huán)節(jié)非常重要,它就是一個出“故障”的環(huán)節(jié),絕不能因其簡單而忽視或輕視這一環(huán)節(jié);二是在故障排除過程中,不能因一時一事的失敗而氣餒,那樣只會半途而廢、功敗垂成,而應(yīng)鍥而不舍、堅持不懈,冷靜、客觀、全面地分析故障對象,運用一切技術(shù)手段,多角度、多層面不斷由表及里,才能直達(dá)病灶,取得成功;三是應(yīng)多從用戶角度出發(fā),多為用戶著想,樹立用戶至上的理念,這樣才能得到最優(yōu)解決方案。