SQL Story摘錄(六)————不可能的錯誤 (轉)
先看這個:
例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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Story摘錄(四)————資訊挖掘初步 (轉)SQL
- 《SQL Story》摘錄五——關係真相 (轉)SQL
- SQL Story摘錄(八)————資料抽取 (轉)SQL
- SQL Story摘錄(七)————觸控NULL值 (轉)SQLNull
- SQL Story摘錄(一)————簡單查詢初探 (轉)SQL
- SQL Story摘錄(三)————可擴充套件設計 (轉)SQL套件
- mysql 解決字符集錯誤 正確摘錄MySql
- SQL Story(十一)--樹狀表遊戲 (轉)SQL遊戲
- 記錄錯誤並繼續執行:錯誤事件記錄子句 --轉事件
- sql_轉摘_提取每行記錄多列的排名前3大值SQL
- ORA-00054錯誤解決方案(摘)
- 核心除錯神器SystemTap 轉摘除錯
- SQL4必知必會摘錄(一)SQL
- SQL必知必會4-摘錄二SQL
- DBA常用資料庫管理SQL (摘錄整理)資料庫SQL
- SQL Server的“錯誤:9004”SQLServer
- rebuttal 摘錄
- SQL Story(十)————遊標的應該與不應該 (轉)SQL
- 常見的錯誤 SQL 用法SQL
- SQL Server 容易忽略的錯誤SQLServer
- 記錄一次根據錯誤資訊無法定位錯誤的錯誤
- Kafka錯誤記錄Kafka
- oracle sql tuning_in與exists的區別_轉摘OracleSQL
- 【摘錄】index(一)Index
- sql語句錯誤SQL
- 急 !!SQL SERVER錯誤SQLServer
- Go語言的表達性、錯誤處理方法和泛型等討論摘錄 - 駭客新聞Go泛型
- 不可能的任務?(轉)
- IT專案管理的六種錯誤思維專案管理
- [摘錄] 基於索引的SQL優化之降龍十八掌索引SQL優化
- lftp學習備記錄--轉摘於網上FTP
- Sql server資料庫人員:常見錯誤(轉)SQLServer資料庫
- C++錯誤記錄C++
- SpringMVC錯誤記錄SpringMVC
- PbootCMS錯誤提示:執行SQL發生錯誤!錯誤:no such column: def1bootSQL
- progit摘錄筆記Git筆記
- <摘錄>GCC 中文手GC
- 物件導向(摘錄)物件