buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

【思路决定出路】换一种思路,柳暗花明---程序如何利用SQL的LIKE实现模糊查询数据

很多公司,尤其互联网公司,都把“思路决定出路”以各种形式写在企业文化墙上。配套的好像还有两句,记不得了(通常这时候我会百度一下……)。

 

说一个老生常谈的场景,一些运营后台常见的模糊查询数据功能。

数据访问架构:开发语言.net(C#),orm是dapper,db是mysql。
对于dapper框架,模糊查询需要先写sql语句,然后通过MySqlConnection的Query<T>从db把满足条件的数据检索出来。
既然是关键字模糊匹配,就要用到LIKE了。

 

一开始的sql也许是这样的:

public static List<t_info_payaccount> GetList(t_info_payaccount ifModel)
{
    string sql = "SELECT * FROM t_info_payaccount WHERE 1=1 ";
    ...
    if (null != ifModel.MerName && ifModel.MerName.Trim() != "")
    {
        sql += " AND merName LIKE '%@merName%'";
        ifModel.MerName = ifModel.MerName.Trim();
    }
    using (var conn = ConnUtility.GateWayConntion)
    {
        return conn.Query<t_info_payaccount>(sql, new
        {
            ...
            merName = ifModel.merName,
            ...
        }).ToList();
    }
}

 

自测发现,db里明明有数据,却LIKE不出来。
这时,你可能感觉很奇怪,程序也没有异常,为什么就是不出来呢。你马上想到的是:我要看看最终执行的sql是什么?SqlServer是可以通过Profiler工具来跟踪执行的sql指令的。mysql不清楚怎么搞出来?然后开始百度“mysql 监测请求的sql语句”
扫了一些网页,太麻烦。————现在搜索技术很先进,百度一下就一大堆。我们对搜索引擎的依赖非常之大,以至于甚至我们常常不假思索遇到问题就百度。就是我们常说的“面向百度编程”。这个习惯对我们来说危害性还是挺大的,很多的百度一下,并没有让我们有所收获,反而是带走了我们很多的时间。其实,有一些开发经验的,用右脑先分析一下,你就知道,'%@merName%'中因为中间的“%@merName%”被“'”引起来了,那必然是当成文本了。所以,你后边指定的参数值也就用不上了。

 

也许,你改为这么实现:

 

    ...
    if (null != ifModel.MerName && ifModel.MerName.Trim() != "")
    {
        sql += " AND merName LIKE '%'+@merName+'%'";
        ifModel.MerName = ifModel.MerName.Trim();
    }
    ...

 

 

 

自测发现,程序出了异常。

错误码: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '+'厦门%'' at line 3
这是因为在mysql语句里,字符串的连接不是用+,而是用CONCAT(str1,str2,...)函数。然后改成用这个函数就可以了。 程序是ok了,殊不知,这样子的实现,并非完美。首先,sql里有函数会降低查询性能。另外,依赖db自带的函数,如果这样的依赖太多,那么,一旦日后将mysql改成mssql,重构就变得很糟糕。

 

来吧,让我们写最简单的sql,至于逻辑,则交给程序。就像下面这样子,是不是很好?

    ...
    if (null != ifModel.MerName && ifModel.MerName.Trim() != "")
    {
        sql += " AND merName LIKE @merName";
        ifModel.MerName =string.Format("%{0}%", ifModel.MerName.Trim());
    }
    ...

 

 

 

 

posted on 2017-02-24 17:35  buguge  阅读(441)  评论(0编辑  收藏  举报