某表含有N個字段超精簡模糊查詢方法


我們在做多個字段模糊查詢時,是不是覺得非常麻煩?比如我要模糊查詢某表多個字段存在某數據時,如下

 

select * from table where a like '%key%' or b  like '%key%' or c like '%key%'..........

 

上面的語句不但長,而且寫起來好麻煩。我們是不是有更好的辦法呢?

答案是肯定的。我們可以這樣寫:

SELECT * FROM  table where CONCAT(a,b,c......) like '%key%'

這樣不就顯得很簡單,很簡潔?

 

如果存在N個字段,而你又不情願一個一個的手寫每個字段,你又該如何呢?

我的思路是這樣的,首先讀取某表所有的字段,比如讀出來某表含有a,b,c,d....等字段(select name from syscolumns where id=object_id(TableName)語句可以讀取某表字段信息),

然后將這些字段拼接到concat中,拼接的結果像這樣的:SELECT * FROM  table where CONCAT(a,b,c......) like '%key%'

這樣一來,簡單了很多,減少了繁瑣不必要的sql拼接操作。

本人為了這個問題,也做了一些程序demo,以便大家互相學習。

0.列名實體類

  public class SysColumns
    {
        public string Key { get; set; }
        public string ColumnName { get; set; }
    }

 

1,枚舉查詢倒序,排序

    public enum OrderType
    {
        /// <summary>
        /// 倒序
        /// </summary>
        Desc = 0,
        /// <summary>
        /// 順序
        /// </summary>
        ASC = 1,
    }

 2.分頁實體類

public class Paging
    {
        /// <summary>
        /// 總數
        /// </summary>
        public int TotalItems { get; set; }
        /// <summary>
        /// 每頁多少條
        /// </summary>
        public int ItemsPerPage { get; set; }
        /// <summary>
        /// 當前頁
        /// </summary>
        public int CurrentPage { get; set; }
        /// <summary>
        /// 總共多少頁
        /// </summary>
        public int TotalPages
        {
            get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
        }

3.帥選條件

  public class SelectField
    {
        /// <summary>
        /// 表名
        /// </summary>
        public string TableName { get; set; }

        /// <summary>
        /// 查找的關鍵字
        /// </summary>
        public string Key { get; set; }

        /// <summary>
        /// 其他條件
        /// </summary>
        public string OtherWhere { get; set; }

        /// <summary>
        /// 排序字段
        /// </summary>
        public string OrderField { get; set; }

        /// <summary>
        /// 排序類型
        /// </summary>
        public string OrderType { get; set; }
    }

4.封裝的方法

    public class SelectForMoreField<T> where T : new()
    {
        private string conn = null;
        /// <summary>
        /// 連接字符串
        /// </summary>
        public SelectForMoreField()
        {
            conn = ConfigurationManager.ConnectionStrings["Conn"].ConnectionString;
        }
        /// <summary>
        /// 判斷SqlDataReader是否存在某列
        /// </summary>
        /// <param name="dr">SqlDataReader</param>
        /// <param name="columnName">列名</param>
        /// <returns></returns>
        private bool readerExists(SqlDataReader dr, string columnName)
        {
            dr.GetSchemaTable().DefaultView.RowFilter = "ColumnName= '" + columnName + "'";
            return (dr.GetSchemaTable().DefaultView.Count > 0);
        }
        /// <summary>
        /// 帶有分頁的多字段查詢
        /// </summary>
        /// <param name="TableName">表名</param>
        /// <param name="KeyWord">查詢關鍵字</param>
        /// <param name="page">當前頁號</param>
        /// <param name="take">每頁顯示行數 </param>
        /// <returns></returns>
        public IList<T> QueryForMoreField(SelectField field, Paging page)
        {
            IList<SysColumns> ls = GetTableField(field.TableName);
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT [t1].* FROM (SELECT ROW_NUMBER() OVER (ORDER BY [t0]." + field.OrderField + " " + field.OrderType + ") AS [ROW_NUMBER], [t0].* FROM  ");

            sb.Append(field.TableName);
            sb.Append(" AS [t0]");
            sb.Append(" where   ");
            int i = 0;
            sb.Append("CONCAT(");
            foreach (SysColumns sysc in ls)
            {
                sb.Append(" cast(" + sysc.ColumnName + " as nvarchar(max)),");
                if ((ls.Count - 1) == i)
                {
                    sb.Append(" cast(" + sysc.ColumnName + " as nvarchar(max)))");
                    sb.Append(" like  '%" + field.Key + "%'");
                }
                i++;
            }
            if (!String.IsNullOrEmpty(field.OtherWhere))
            {
                sb.Append("and ");
                sb.Append(field.OtherWhere);
            }
            sb.Append("    ) AS [t1] ");
            sb.Append("WHERE [t1].[ROW_NUMBER] BETWEEN ((" + page.CurrentPage + "*" + page.ItemsPerPage + ") - (" + page.ItemsPerPage + " -1)) AND (" + page.CurrentPage + "*" + page.ItemsPerPage + ")");
            sb.Append("ORDER BY [t1].[ROW_NUMBER]");
            string sql = sb.ToString();
            IList<T> list;
            Type type = typeof(T);
            string tempName = string.Empty;
            using (SqlDataReader reader = SqlHelper.ExecuteReader(conn, CommandType.Text, sql))
            {
                if (reader.HasRows)
                {
                    list = new List<T>();
                    while (reader.Read())
                    {
                        T t = new T();
                        PropertyInfo[] propertys = t.GetType().GetProperties();
                        foreach (PropertyInfo pi in propertys)
                        {
                            tempName = pi.Name;
                            if (readerExists(reader, tempName))
                            {
                                if (!pi.CanWrite)
                                {
                                    continue;
                                }
                                var value = reader[tempName];
                                if (value != DBNull.Value)
                                {
                                    pi.SetValue(t, value, null);
                                }
                            }
                        }
                        list.Add(t);
                    }
                    sb = null;
                    sql = null;
                    conn = null;
                    return list;
                }
            }
            return null;
        }
        /// <summary>
        /// 簡單的條件查詢
        /// </summary>
        /// <param name="field">查詢條件</param>
        /// <returns></returns>
        public IList<T> QueryForMoreField(SelectField field)
        {
            IList<SysColumns> ls = GetTableField(field.TableName);
            StringBuilder sb = new StringBuilder();
            sb.Append("SELECT * FROM " + field.TableName);
            sb.Append(" where   ");
            int i = 0;
            sb.Append("CONCAT(");
            foreach (SysColumns sysc in ls)
            {
                sb.Append(" cast(" + sysc.ColumnName + " as nvarchar(max)),");
                if ((ls.Count - 1) == i)
                {
                    sb.Append(" cast(" + sysc.ColumnName + " as nvarchar(max)))");
                    sb.Append(" like  '%" + field.Key + "%'");
                }
                i++;
            }
            string sql = sb.ToString();
            IList<T> list;
            Type type = typeof(T);
            string tempName = string.Empty;
            using (SqlDataReader reader = SqlHelper.ExecuteReader(conn, CommandType.Text, sql))
            {
                if (reader.HasRows)
                {
                    list = new List<T>();
                    while (reader.Read())
                    {
                        T t = new T();
                        PropertyInfo[] propertys = t.GetType().GetProperties();
                        foreach (PropertyInfo pi in propertys)
                        {
                            tempName = pi.Name;
                            if (readerExists(reader, tempName))
                            {
                                if (!pi.CanWrite)
                                {
                                    continue;
                                }
                                var value = reader[tempName];
                                if (value != DBNull.Value)
                                {
                                    pi.SetValue(t, value, null);
                                }
                            }
                        }
                        list.Add(t);
                    }
                    sb = null;
                    sql = null;
                    conn = null;
                    return list;
                }
            }
            return null;
        }
        /// <summary>
        /// 獲取表中所有字段
        /// </summary>
        /// <param name="TableName">表名</param>
        /// <returns></returns>
        public IList<SysColumns> GetTableField(string TableName)
        {
            SqlDataReader read = SqlHelper.ExecuteReader(conn, CommandType.Text, "select name from syscolumns where id=object_id('" + TableName + "')");
            IList<SysColumns> ls = new List<SysColumns>();
            while (read.Read())
            {
                SysColumns co = new SysColumns();
                co.Key = Guid.NewGuid().ToString().Replace("-", "");
                co.ColumnName = read.GetString(0);
                ls.Add(co);
            }
            read.Close();
            return ls;
        }
    }

 5.調用演示

  class Program
    {
       // static string conn = ConfigurationManager.ConnectionStrings["Conn"].ConnectionString;
        static void Main(string[] args)
        {
            SelectForMoreField<Product> ls = new SelectForMoreField<Product>();
            SelectField field = new SelectField();
            field.TableName = "Product";
            field.Key = "1";
            field.OtherWhere = "Id > 12281";
            int y = (int)OrderType.Desc;
            field.OrderType = ((OrderType)y).ToString();
            field.OrderField = "Id";
            Paging page = new Paging();
            page.CurrentPage = 1;
            page.ItemsPerPage = 10;
            IList<Product> data = ls.QueryForMoreField(field, page);
            foreach (var d in data)
            {
                Console.WriteLine("ID:"+d.Id+" Name"+d.Name);
            }
        }

 

 

 

 

 

注:這只是個簡陋粗糙的實現而已,后續精簡程序,拓展Linq 這類方法,程序無法提供下載,因為不知道博客園編輯器如何上傳,見諒。

注意:本程序支持sql2008 R2以上的數據庫

 


免責聲明!

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



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