• SELECT 語法中,如何動態組合查詢條件(转)


    假如有個畫面提供許多輸入項目,例如,姓名,電話,地址.....等查詢條件,因為使用者可能會任意輸入某幾個項目進行查詢,此時我們的 WHERE 條件該如何動態組合這些情況,將結果提供給查詢的人呢?

    這個問題乍看之下好像不是什麼大問題,一旦開始嘗試解決,卻可能會不小心陷入思考的泥淖而難以自拔!

    為了減輕許多朋友的困擾,這裡提供個人的解決方法供大家參考。當然,若您有更棒的想法,歡迎一起討論!

    那麼我們就開始吧!


    這個問題基本上是一個 WHERE 條件動態組合的問題,但若直接想成只有瀏覽者有輸入(TextBox)或有選擇(DropDownList)的欄位才納入 WHERE 條件中,那麼組合的情況將隨著查詢條件的增加而快速暴增。

    例如,有 name,area,tel 三個項目時,瀏覽者可能會任意輸入其中一個,或兩個 ... 當作查詢條件,放在 WHERE 條件的情況可能有下面七種組合
    1. name
    2. area
    3. tel
    4. name, area
    5. name, tel
    6. area, tel
    7. name, area, tel

    而這還只是三個查詢欄位而已,若是有六個,七個,甚至十幾個呢? 只要查詢欄位數目不同,就必須重新思考組合方式,既容易漏了某個組合,也很容易在程式寫作中出錯,夠折騰人了。因此必須另謀出路,才能跳出上述思考方式的痛苦魔咒。

    個人提出一個解決方式,供大家參考(以 TextBox 的文字輸入說明)。主要的思考核心是

    1. 將所有查詢欄位全部放在 WHERE 條件中
    2. 此時,所有欄位只有兩種情況:
      a. 若某欄位被用來查詢時,語法如下
      欄位名稱 LIKE '%瀏覽者輸入之文字%'
      b. 若某欄位瀏覽者並未用來查詢時,該欄位並未影響紀錄的選取,因此語法可改成
      欄位名稱 LIKE '%' OR 欄位名稱 IS NULL

      上述的方式可大量簡化組合的方式。

      把這樣的觀念寫成下面的輔助方法,可以方便重複使用
    public static string Where_QuerySomething(string qStr, string fieldName, string paraName, bool isFirst, SqlCommand cmd)
    {
    string result = " AND ";
    if (isFirst) result = "";
    if (qStr.Trim() == "")
    result += " (" + fieldName + " LIKE '%' OR " + fieldName + " IS NULL)";
    else {
    result += " (" + fieldName + " LIKE " + paraName + ")";
    SqlParameter para = new SqlParameter(paraName, SqlDbType.VarChar, 256);
    para.Value = "%" + qStr + "%"; cmd.Parameters.Add(para);
    }
    return result;
    }

    說明:
    Where_QuerySomething 的
    第一個參數 qStr:瀏覽者想查詢所輸入的字串
    第二個參數 fieldName:資料表欄位名稱
    第三個參數 paraName:SELECT 語法中,WHERE 條件裏的參數名稱,例如 @name
    第四個參數 isFirst:布林值,WHERE 條件裏排在第一個的為 true,排在其後的皆為 false
    第五個參數 cmd:所使用的 SqlCommand 物件

    使用方式
    //查詢
    public static DataSet Query(string CustNo, string CustName, string VIPNo) {
    SqlConnection cn = new SqlConnection("連線字串");
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = cn;

    //--- 查詢之 WHERE 條件處理 -----------------------------
    //客戶編號

    string tCustNo = Where_QuerySomething(CustNo, "a.CustNo", "@CustNo", true, cmd);
    //客戶名稱
    string tCustName = Where_QuerySomething(CustName, "a.CustName", "@CustName", false, cmd);
    //VIP 卡號
    string tVIPNo = Where_QuerySomething(VIPNo, "a.VIPNo", "@VIPNo", false, cmd);
    //-----------------------------------------------------------------------------
    cmd.CommandText = " SELECT * FROM CustTB " + " WHERE " + tCustNo + tCustName + tVIPNo; //將上面處理後的字串串接

    //--- 開始處理 -----------------------------------------------------------------
    DataSet ds = new DataSet();
    SqlDataAdapter da = new SqlDataAdapter(cmd);

    try { da.Fill(ds); }
    catch (Exception e) { throw e; }
    finally { if (cn.State != ConnectionState.Closed) cn.Close(); }

    return ds;
    }
  • 相关阅读:
    几种负载均衡技术的实现
    gevent和tornado异步
    Android笔记:invalidate()和postInvalidate() 的区别及使用——刷新ui
    ubuntu终端颜色配置
    应用程序基础及组件(续)
    安卓架构
    Linux下安卓ndk混合编译调用so方法——QuickStart学习
    JAVA反射机制
    BroadcastReceiver应用详解——广播
    库会因为权限问题无法打开——selinux开启严格模式
  • 原文地址:https://www.cnblogs.com/Fskjb/p/1704046.html
Copyright © 2020-2023  润新知