某表含有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以上的数据库

某表含有N个字段超精简模糊查询方法

时间: 2024-08-28 16:22:29

某表含有N个字段超精简模糊查询方法的相关文章

Sqlite创建表一定要声明字段类型(ContentProvider查询的小问题)

用ContentProvider查询,有时候不太灵..就像下面的代码,数据库中存在该数据,但是查不出来.原因可能是该字段没有声明类型.. 如下: private final static String SQL_CREATE_TABLE_INSTALLED = "CREATE TABLE if not exists " + TABLE_INSTALLED + " ( " + "id not null, " + "name text not

关于mongodb按照字段模糊查询方法

模糊查询:tname包含某个关键字测试' cd /opt/soft/mongodb/bin ./mongo --host 192.168.0.1  --port 17017  test db.test_info.find({"tname": {$regex: '测试', $options:'i'}}) db.test_info.find({"tname": {$regex:/测试.*/i}})

oracle判断表中的某个字段是否为数字

本文分别介绍使用trim+translate函数或regexp_like函数判断表中的某个字段是否为数字的方法 1.使用trim+translate函数: select * from table where trim(translate(column,'0123456789',' ')) is NULL; 这里要注意的是:translate函数的第三个参数是一个空格,不是'', 因为translate的第三个参数如果为空的话,那么永远返回'',这样的就不能达到过滤纯数字的目的.这样把所有的数字都

Spring data jpa模糊查询,根据某一个字段,或者多个字段进行模糊查询

这里分别列举里三种情况: 1.一个字段的模糊查询 2.一个字段模糊查询和一个字段不支持模糊查询 3.两个以上的字段支持模糊查询 刚开始,使用like发现并不起作用,后来经同事帮忙,才改成的Containing关键字:     public List<Nodes> findByIpContaining(String ip, Pageable pageable);     public List<Nodes> findByIpContainingAndStatus(String ip,

修改MySQL数据库中表和表中字段的编码方式的方法

今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1,然后再次仔细观察控制台输出的异常,进一步确定是表和表中字段编码不当造成的,那就修改表和其中对应的字段呗,网上找了一会儿,你别说还真有,执行完sql脚本后果然可以存入中文了,尽管如此还是认为有必要总结一下,古人云:好记性不如烂笔头嘛,呵呵呵. 修改表的编码方式:ALTER TABLE `test`

一个表里有多个字段需要同时使用字典表进行关联显示,如何写sql查询语句

参考:https://bbs.csdn.net/topics/330032307 数据库里面有一个字典表,这张表里面有id段和对应的名字字段.在另外一个记录的表里面有对应的上述字典表的id,而且有多个字段都含有该id字段.需要将其查出来,并且用名字. SELECT a.id AS '编号', 'STORY' AS '类型' , a.title AS '标题',b.name AS '所属项目' ,a.project AS '所属项目' , c.realname AS '创建者', a.estima

存储引擎、表的创建、字段的各种数据类型、模糊匹配、严格模式、约束条件等

存储引擎: 不同类型的数据拥有不同的处理机制. mysql存储引擎 Innodb:默认的存储引擎 查询速度较myisam慢 但是更安全 myisam:mysql老版本用的存储引擎,比较innodb memory:内存引擎(数据全部存在内存中) blackhole:无论存什么 都立马消失(黑洞) 研究一下每个存储引擎存取数据的特点 show engines; 数据类型 整型 浮点型 字符类型 日期类型 枚举与集合类型 约束 not null unique default primary key t

SqlServer给一个表增加多个字段语法

添加字段语法 alter table table_name add column_name +字段类型+ 约束条件 给一个表增加多个字段: use NatureData go alter table XunHu add MaleCount varchar(50) null, FemaleCount varchar(50) null, SubadultCount varchar(50) null, LarvaeCount varchar(50) null, TraceType varchar(50

一条SQL语句查询两表中两个字段

首先描述问题,student表中有字段startID,endID.garde表中的ID需要对应student表中的startID或者student表中的endID才能查出grade表中的name字段,这时候问题就来了,如果需要一条sql一句同时查出garde表中的两条数据怎么办?(两表的关联字段为 SID) sql="select b.name,c.name as name2 from student a,garde b,grade c where a.SID=b.SID and a.SID=c