动态组装sql(解决where1=1低效的方案)
来源:互联网 发布:自考和网络教育认可度 编辑:程序博客网 时间:2024/04/30 04:04
要实现这种动态的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”的过滤条件以后数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫
对每行数据进行扫描(也就是全表扫描)以比较此行是否满足过滤条件,当表中数据量比较大的
时候查询速度会非常慢。因此如果数据检索对性能有比较高的要求就不要使用这种“简便”的方
式。下面给出一种参考实现,伪代码如下:
private void doQuery()
{
Bool hasWhere = false;
StringBuilder sql = new StringBuilder(" SELECT * FROM T_Employee");
if(工号复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FNumber BETWEEN '"+工号文本框1内容+"' AND '"+工号
文本框2内容+"'");
}
if(姓名复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FName LIKE '%"+姓名文本框内容+"%'");
}
if(年龄复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2
内容);
}
executeSQL(sql);
}
private Bool appendWhereIfNeed(StringBuilder sql,Bool hasWhere)
{
if(hasWhere==false)
{
sql. appendLine("WHERE");
}
else
{
个复选框是否选中来向这个字符串中添加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”的过滤条件以后数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫
对每行数据进行扫描(也就是全表扫描)以比较此行是否满足过滤条件,当表中数据量比较大的
时候查询速度会非常慢。因此如果数据检索对性能有比较高的要求就不要使用这种“简便”的方
式。下面给出一种参考实现,伪代码如下:
private void doQuery()
{
Bool hasWhere = false;
StringBuilder sql = new StringBuilder(" SELECT * FROM T_Employee");
if(工号复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FNumber BETWEEN '"+工号文本框1内容+"' AND '"+工号
文本框2内容+"'");
}
if(姓名复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FName LIKE '%"+姓名文本框内容+"%'");
}
if(年龄复选框选中)
{
hasWhere = appendWhereIfNeed(sql, hasWhere);
sql.appendLine("FAge BETWEEN "+年龄文本框1内容+" AND "+年龄文本框2
内容);
}
executeSQL(sql);
}
private Bool appendWhereIfNeed(StringBuilder sql,Bool hasWhere)
{
if(hasWhere==false)
{
sql. appendLine("WHERE");
}
else
{
sql. appendLine("AND");
}
}
0 0
- 动态组装sql(解决where1=1低效的方案)
- 动态组装sql(解决where1=1低效的方案)
- 动态组装sql(解决where1=1低效的方案)
- 低效的“WHERE1=1”
- 低效的where1=1
- 低效能的”where1=1”
- 数据库2_低效能的”where1=1”
- where1=1的sql查询功能
- sql语句中where1=1的用处
- SQL中where 1=1 和 where1<>1
- 数据库语句where1=1的用法和作用
- 有关数据库中添加 where1=1 的问题
- 识别低效的SQL语句
- 查询低效SQL的语句
- ANDROID FRAMENT的切换(解决REPLACE的低效)
- android Fragment的切换(解决replace的低效)
- Android Frament的切换(解决replace的低效)
- 低效的“WHERE 1=1”
- Nginx学习笔记(二十):内存池分析
- 用Java分析C源代码中头文件使用频率
- 链栈的Push和Pop
- Unicode 基本语调符
- 免费接口API
- 动态组装sql(解决where1=1低效的方案)
- 一秒钟法则:来自腾讯无线研发的经验分享
- C# VS2010中引用Alchemy Websockets出错的解决方案
- 不再放手
- 【线程】Java线程(1)-线程基本理解and实现方式
- 《深入网站开发和运维》
- Android Volley完全解析(二),使用Volley加载网络图片
- JavaScript(1)开篇
- 第二讲 探秘微信公众号