編程經驗點滴----動態 SQL 的拼接技巧


最近在博客園上,看到經常有人誤解動態 SQL 的拼接。比如我的一篇博客文章:

 

評“CPQuery, 解決拼接SQL的新方法”
http://www.cnblogs.com/jacklondon/archive/2012/09/11/2679738.html?updated=1

 

眾多人在回復,其中至少有三位老兄,誤解了動態 SQL 的拼接。

特寫此文,闡述一下其中的技巧。希望能糾正初學者的錯誤。

 

常見的誤解有:

1. 只用 ado.net ,無法進行動態 SQL 拼接。

2. 有幾個動態參數,代碼的重復量就成了這些參數的不同數量的組合數,動態參數越多,重復量越大。

對於第二個問題,以下的錯誤代碼為其證據:

if(id>0 && string.IsNullOrEmpty(name))
{
    command.CommandText = "select * from t1 where id=?";
    command.Parameters.Add(id);
}
if(id<=0 && !string.IsNullOrEmpty(name))
{
    command.CommandText = "select * from t1 where name=?";
    command.Parameters.Add(name);
}
if(id<=0 && !string.IsNullOrEmpty(name))
{
    command.CommandText = "select * from t1 where id=? and name=?";
    command.Parameters.Add(id);
    command.Parameters.Add(name);
}

 

這兩個問題都很好解決,給一個正確的代碼例子大家看看即可:

string sql ="select * from t1 where 1=1";
if(id != null)
{
    sql += " and id=?";
    addParameterValue(cmd,id); 
}
if(!string.IsNullOrEmpty(name))
{
    sql += " and name=?";
    addParameterValue(cmd,name); 
}
command.CommandText = sql;

這里的技巧在於,使用了一個 "where 1=1", 巧妙解決了后續 sql 拼接中,每行開頭是否要有 "and" 的問題。而這個 "where 1=1",並不會對數據庫的索引執行,造成性能上的影響。

 

對參數進行排列組合,然后寫各種組合的 SQL,這個思路很奇怪。問題是,很多初學者,都有這個思維習慣。本人不是計算機科班出身,不知道是否哪本教科書,就是如此教導的。但很不幸的是,這個錯誤思維習慣廣泛存在於很多人的心中。

"where 1=1" 雖是教科書中沒有的小技巧,卻很管用。

 

另外,在程序中,一般會在用戶界面上讓使用用戶錄入數字,這個數字的數值,在代碼中會自動變成 string,然后嘗試 string 轉換成 int/long,最后送到 sql 函數里。這里需要特別注意的是,很多人把某個特殊的數值,作為“用戶無錄入的默認值”,正如本文開頭所寫的錯誤代碼那樣:

if(id>0 && string.IsNullOrEmpty(name))

 

問題在於,0 是否是不正常的業務數值,代碼中看不出來。不排除程序員隨意指定一個數值,作為“用戶無錄入的默認值”,如果不巧這個默認值,有其他意義的,那就造成問題。

 

在數據庫的理論中,沒有指定的數據,是用 null 來表示的,不論是 string 還是 int/long。

這是一個很好的思路,同樣可以用在這里的 sql 拼接中。因此,我們在后面的代碼中,使用了這個:

if(id != null)

 

上述代碼中,

addParameterValue(cmd,name); 

是一個簡單封裝的函數,用來封裝如下一小段代碼,目的是讓最后的代碼,較為簡捷直觀:

        DbParameter p = cmd.CreateParameter(); 
        p.ParameterName = "@XXX"; 
        p.Value = TTT; 
        cmd.Parameters.Add(p);

 

當然,這個 addParameterValue() 封裝函數,是可有可無的。多寫幾個 DbParameter p = cmd.CreateParameter() 並沒有什么大問題。 

 

-------------歡迎大家下載試用折桂單點登錄系統, http://zheguisoft.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM