改善sql字符串的可讀性 - sql字符串常見編寫風格

 

所謂的動態sql,就是在t-sql字符串內的sql,而靜態sql就是直接寫在t-sql 存儲過程內的。動態sql的好處是可以寫出非常複雜的,表達能力很強的sql,並且,因爲某些條件下sql更簡單,因此號稱效率更好。而靜態sql的好處在於可以調試,可以代碼提示。不管怎樣,我發現我們的sql很多都是動態的。尤其是在sqlserver缺乏分頁支持的sql2000,很多需要分頁的存儲過程都是這樣的。動態sql的強大能力來自於字符串的拼接,因此,如何改善字符串拼接就是對代碼可讀性進行優化的關鍵。如果能夠改成靜態sql而不必犧牲性能就更好了。

 

1. 加號拼接

這是最常見的拼接,特點是好寫,缺點是難讀。很多時候容易寫的代碼往往不容易閱讀——因爲不需要爲變量取名字,完全就是具體數值的思維就可以。而需要參數化的sql語句,需要的是稍微抽象的參數化的思維。不過參數化的思維也不難,畢竟我們從初一就開始學習參數化的數學了。

 

Sql = "select top 1 typeid,sonnum,deleted from ptype where (usercode='" + pFullName + "' or fullname='" + pFullName + "') and typeid ='" + ptypeid + "'";

 

代碼表示更加usercodefullnametypeid的條件,列出 ptype表的第一行。這裏面的“+”的引入,導致整個sql在閱讀角度看起來是支離破碎,難以一目瞭然的瞭解代碼的意圖。其中的涉及到sql字符串定界符的“’”的處理也讓人覺得很傷心。

 

儘管以c#代碼爲例,但是在t-sql內利用“+”來拼接也不在少數,表現的問題也差不多一樣。

 

2. format拼接

還是以同樣的代碼爲案例,以格式化函數的方式來看:

 

Sql = "select top 1 typeid,sonnum,deleted from ptype where (usercode='{0}'' or fullname='{0}') and typeid ='{1}'";

Sql=string.format(sql,fullname,typeid);

 

儘管增加了一個函數,但是sql顯然變得比較完整,sql本身不完整的信息,以參數的方式提出來,“'”帶來的閱讀干擾也不像“加號拼接”那麼礙眼。當然問題也是存在的:首先因爲參數採用數字,因此當sql大些,參數多些的時候,找到參數對應關係會變得很麻煩。其次,依然存在sql injectionsql注入)的問題。

 

3. AddParameter拼接

 

還是以同樣的代碼爲案例,以格式化函數的方式來看:

 

Sql = "select top 1 typeid,sonnum,deleted from ptype where (usercode=@fullname or fullname=@fullname) and typeid =@typeid";

db.AddParameter("@fullname", fullname);

db.AddParameter("@typeid",typeid);

 

我個人認爲,這個方式的拼接sql方法是最好的。不但sql可以完整的閱讀,參數還是有名稱的——這樣即使參數很多,sql很長,對閱讀的額外障礙也不多。也不存在sql injection問題。至於"'"也無需考慮了。 但是需要爲變參想名字,這是寫起來要麻煩的一個原因吧。

 

這三種sql拼接的風格,都是以c#爲例的,但是對存儲過程也是一樣的效果。僅僅是換門語言而已。

 

側寫:我看過的克服“‘”閱讀干擾的方法:

 

採用 CHAR(10)來替代"'"

 

SET @strSQL=@strSQL+'                LEFT JOIN SCM_BillType t ON a.BillType = t.BillType '+CHAR(10)

SET @strSQL=@strSQL+'                LEFT JOIN Pub_DType d ON a.DID = d._ID '+CHAR(10)

 

這段代碼還表明,作者希望通過left join前面加入很多空格來對齊,一邊可以print來查看最後的sql是什麼。看來,這個sql的作者寫代碼的時候也是希望看到完整的sql的。

改善sql字符串的可讀性 - sql字符串常見編寫風格

2010518

10:31

 

發佈了4 篇原創文章 · 獲贊 0 · 訪問量 2295
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章