SQL 多条件查询 where 1=1

要实现这种动态的SQL语句拼装,我们可以在宿主语言中建立一个字符串,然后逐个判断各个复选框是否选中来向这个字符串中添加SQL语句片段。这里有一个问题就是当有复选框被选中的时候SQL语句是含有WHERE子句的, 而当所有的复选框都没有被选中的时候就没有WHERE子句了,因此在添加每一个过滤条件判断的时候都要判断是否已经存在WHERE语句了,如果没有WHERE语句则添加WHERE语句。 在判断每一个复选框的时候都要去判断, 这使得用起来非常麻烦,“聪明的程序员是会偷懒的程序员”,因此开发人员想到了一个捷径:为SQL语句指定一个永远为真的条件语句(比如“1=1”),这样就不用考虑WHERE语句是否存在的问题了。伪代码如下:

String sql = " SELECT * FROM T_Employee WHERE 1=1"; 
if(工号复选框选中) 
{ 
sql.appendLine("AND FNumber BETWEEN '"+工号文本框1内容+"' AND '"+工号文本框2内容+"'"); 
} 
if(姓名复选框选中) 
{ 
sql.appendLine("AND FName LIKE '%"+姓名文本框内容+"%'"); 
} 
if(年龄复选框选中) 
{ 
sql.appendLine("AND FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2内容); 
} 
executeSQL(sql);
这样如果不选中姓名和年龄前的复选框的时候就会执行下面的SQL语句:
SELECT * FROM T_Employee WHERE 1=1 
AND FNumber BETWEEN 'DEV001' AND 'DEV008' 
AND FSalary BETWEEN 3000 AND 6000
而如果将所有的复选框都不选中的时候就会执行下面的SQL语句:
SELECT * FROM T_Employee WHERE 1=1



这看似非常优美的解决了问题,殊不知这样很可能会造成非常大的性能损失,因为使用添加了“1=1”的过滤条件以后数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(也就是全表扫描)以比较此行是否满足过滤条件,当表中数据量比较大的时候查询速度会非常慢。因此如果数据检索对性能有比较高的要求就不要使用这种“简便”的方式。下面给出一种参考实现,伪代码如下:


StringBuilder buff = new StringBuilder("select * from T ")
String sp = " WHERE ";
foreach() {
if (...) {
buff.append(sp).append(cond);
sp = " AND ";
}
}


但是where 1=1真的低效么?答案是不影响。

   因为查询分析器在代数树优化阶段就把1=1 直接给过滤掉了。这个功能就是查询优化器中所谓的“Constant Folding”。

深入了解参见:https://www.cnblogs.com/CareySon/p/4138575.htm



阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页