【思路决定出路】换一种思路,柳暗花明_sql

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

 

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

数据访问架构:db是mysql,orm是dapper。开发语言.net(C#)
对于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+'%'";
}
...

 

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

错误码: 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,重构就变得很糟糕。

 

也许,这样实现才算好:

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

 

写最简单的sql,至于逻辑,则交给程序。是不是很好?