SQL Story摘錄(六)————不可能的錯誤 (轉)

worldblog發表於2007-12-13
SQL Story摘錄(六)————不可能的錯誤 (轉)[@more@] 初學的日子,感覺就像是剛學走路,步態可掬,跌跌撞撞。摔了不少可笑的跟頭。拿出來大家娛樂一下,也互相提個醒,這樣的錯我們可以儘量避免的嘛。

先看這個:

例1 不合理的逗號:

Field1, Field2, Field3, From MyTable

一就是個語法錯誤,什麼意思嘛,這可是從書上抄的哎,你不能這麼對我……呵呵呵,其實嘛,錯誤在於我在最後一個欄位名後面加了一個逗號。逗號是分隔欄位名或表名的嘛,欄位名和Form之間加個逗號算什麼事?不要小看它,即使老手,也常出這個錯,往往是因為這種情況:我們寫了一個

Select Field1,

Field2,

Field3

From MyTable

……

然後過程中,我們可能會增刪一些欄位,尤其是在From關鍵字前面增刪欄位時,常會搞出事來,忘了看是不是欄位間都由逗號分隔並且沒有多餘的逗號,常見是:

Select Field1,

Field2,

From MyTable

……

或者

Select Field1,

Field2,

Field3

Field4

From MyTable

……

Field3和Field4之間應有的逗號不見了,要是你寫的是“Select ……Field3 as “XXX” Field4…… ”還好,會馬上發現這裡有錯,不讓你透過語法檢查。如果是像前面那樣寫就慘了,系統會以為這是你給Field3起的別名哪,它會老老實實地輸出:

Field1 Field2 Field4

------------------------

…………………………

像我這樣的大馬虎很可能會因為“沒有錯”就這樣過去了,或者很奇怪地找“我的Field3那裡去了”?其實不見了的是Field4……

MCa教材中的SQL採用了一種寫法,初看很奇怪,卻能很有效地防止這類錯誤:

Select Field1

,Field2

,Field3

From MyTable

……

第一個欄位前面有Select關鍵字,其它的欄位前面全有逗號。這種寫法不符合英語的風格,不過朋友們可以試試,當你選中某一個欄位(單行),或某幾欄位(多行),拖動它們,剪下、貼上,修改,幾乎不會導致逗號錯誤。因為一般人的習慣,除錯過程中最常改的就是最後幾個欄位。用這種寫法,總能保證From和它前面的欄位之間沒有逗號,而每個段之間都有逗號。當然Select 和第一個欄位之間有逗號這種錯誤我也犯過(我犯過的錯太多了),不過我的是這種錯誤很容易就會被發現,不像前面提的那兩種那麼隱蔽。當然它真的看起起來不順,所以我到現在也總想不起這麼寫,所以我到現在還是會有時犯這個逗號錯誤。值不值得,請讀者自己選擇吧。

例2 語言問題:

看看這一句,居然也有錯?

Select Field1,

Field2,

Field3

From MyTable

是的,所有的逗號各就各位,而且這個語句如此簡單,實在沒什麼可犯錯的地方啊?其實……Field2後面的那個逗號是不是有點怪怪的?對了,它是個中文逗號,引擎可不認識它。在別的場合裡,可能犯這種錯的機會還少一點,由於我們在資料庫中大量的要和中文資訊打交道,就會經常遇到這種事。不只是逗號,有時我們可能寫一些中文的別名,所以用來標識它的雙引號也有錯寫成中文的危險。在這方面,沒什麼特別的技巧,如果你只用這臺機器寫程式碼,不妨把中文輸入法設成英語標點(我絕不會,因為要寫文章),還有就是一定要用半形數字,用全形數字寫算式,系統可認不出來。

給大家一個比較過分的中文錯誤:

Select  Field1,

Field2,

Field3+1,

    Field4 as “中文欄位名”

From Mytable

看看,中英文混排是不是挺可怕的?

“Form”錯誤

這個比較簡單,就不舉例了,就是一個拼寫錯誤。如果評SQL語言中最容易寫錯的關鍵字,From 一定位居榜首。For和Fo都是英語中很常見的單詞。我相信像我這樣一寫順了就把From寫成Form的肯定還有。如果是在 的查詢分析器或InterBase的ISQL中,還比容易發現,因為From會被加粗或加藍。不過我們經常要在客戶端程式碼中嵌入SQL(比如),那時就比較容易出這個錯了。就在今天白天寫程式時,我還在script指令碼中把一個“Form”寫成了“From”,這回光想著SQL,又給寫反了。對此真的沒什麼好辦法,小心再小心吧。

影子殺手——NULL值

有一個工資表,員工工資有兩種,技術工資和業務工資,每個人根據崗位,發其中一種。現在統計這月公司一共下發多少錢,可能你會這麼查:

SELECT SUM(技術工資+業務工資) FROM 工資表

而一回,結果是0。老闆聽說這事會比較高興,因為他這個月少了一筆大支出,可你卻面臨被同事圍攻的危險了。其實很簡單,你忘了 NULL值。每個人的工資都有一項是NULL,直接一加起來就是NULL,一統計一分錢沒有。

這次不只是細心的問題了,NULL值是SQL語言,乃至整個關係模型中最詭異的東西之一。它是什麼?它什麼也不是,它代表一切不可知的,未知的,未定義的東西。它不是0,更不是空格或空字串。它不是資訊,因為它不代表任何資訊;但它也是資訊,它告訴我們這裡沒有資訊。它是任何型別的資料,因為任何資料都會有NULL;它不是任何型別的資料,因為用任何資料何它比較都沒有意義。《SQL-3 參考大全》中這樣評價:“這是不愉快而且在數學上是不合理的,但是是我們所得到的。”這是一個會讓老手也為之發瘋的東西。它讓我想起很小的時候讀到的一本童話,說童話王國下在被“烏有”吞沒。“烏有”是什麼?它什麼也不是,它沒有顏色,沒有形狀,沒有氣味,它就是什麼也沒有,在“烏有”中什麼也看不到,對,它沒有顏色,可並不代表它是黑的或透明的,“烏有”就是“烏有”,“烏有”侵吞一切,什麼遇上“烏有”都會變成“烏有”。這本書還神神叨叨地寫了其它一大堆很意識流很哲學的東西。我當時讀了這本書整個人都變得神神叨叨的,天天想一些存在啊,自我本我什麼的(那時我在上小學),以致於後來不小心當了程式設計師。後來見到NULL值我才明白,原來那本書的作者一定是一個資料庫程式設計師,搞不好就是E.F.Codd本人。

NULL值是一個很可怕的東西,什麼和它運算都會變成NULL,所以也別指望誰能和它比出大小,連NULL值自己也不行,想知道一個值是不是NULL不能用XXX=NULL,只能用XXX IS NULL。做聯接查詢時,尤其要小心NULL,聯接有內聯,有左右外聯,有全聯接,有Cross Join,就是這原因。更不要提寫一些數學,一定要小心它,必要時一定要用一些方法避免NULL值,比如在設計資料庫時,該有預設值的欄位要設預設值,該要求一定輸入的就設為Not NULL。很多資料庫系統有專用的功能來處理NULL值,在這方面MS SQL Server做的還不錯,有一些比如ISNULL()之類的,功能很全面,用起來也很方便。

關於NULL值,絕對可以單獨擴充出一個很有趣味的專題,但是它本身的確又是最常犯的技術錯誤,所以在這裡一定要提。比如上面的錯誤,有兩種方法可以避免:要麼把兩項空資的預設值都設為0,要麼就用:

SELECT SUM(技術工資)+(業務工資) FROM 工資表

現在,你了。

今天先到這裡,以後有機會,我們還會繼續討論一些更有意思,也更復雜的錯誤,搞清它們,對我們的進步也是很有幫助的。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992746/,如需轉載,請註明出處,否則將追究法律責任。

相關文章