Sql动态查询拼接字符串的优化
Sql动态查询拼接字符串的优化
最原始的 直接写:string sql="select * from TestTables where 1=1";
... 这样的代码效率很低的,这样影响了数据库的索引引用
如下所示:
private void TestOneMethod()
{
string querySql = "select * from TestTables where 1=1";
if (hasOneCondition)
{
querySql += "oneCondition='oneCondition'";
}
if (hasTwoCondition)
{
querySql += "twoCondition='twoCondition'";
}
if (hasThreeCondition)
{
querySql += "threeCondition='threeCondition'";
}
// ....其他条件
// ExcSql(querySql)
}
优化方案A:
去掉 string sql="where 1=1"
那么,在用的时候定义一个变量,用来标志是否应存在了hasWhere=false ,如果已经存在了则 hasWhere=!hasWhere.这样下一次在用的时候就
可以用下面的形式表示了:
private void TestOneMethod()
{
string querySql = "select * from TestTables";
bool _hasWhere = false;
if (hasOneCondition)
{
querySql += _hasWhere ? "where" : "and" + "oneCondition='oneCondition'";
_hasWhere = true;
}
if (hasTwoCondition)
{
querySql += _hasWhere ? "where" : "and" + "twoCondition='twoCondition'";
_hasWhere = true;
}
if (hasThreeCondition)
{
querySql += _hasWhere ? "where" : "and" + "threeCondition='threeCondition'";
_hasWhere = true;
}
// ....其他条件
// ExcSql(querySql)
}
....
经过优化后,sql的效率提高了,但是仍然存在问题,问题在哪里呢?如果我们每次都这样写的话是不是非常的费力,那么就提出一个通用的方
法,这个通用的方法首先得有一个bool类型的返回值,用来确认当前是否需要hasString。如下,在应用的时候:
private bool SeachHelper(string whereString, bool hasWhere)
{
if (!hasWhere)
whereString = "where" + whereString;
else
whereString = "and" + whereString;
return true;
}
private void TestTwoMethod()
{
string querySql = "select * from TestTables";
bool _hasWhere = false;
if (hasOneCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "oneCondition='oneCondition'";
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "twoCondition='twoCondition'";
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql += "threeCondition='threeCondition'";
}
// ....其他条件
// ExcSql(querySql);
}
代码简洁了不少,但是仍然粗只能问题,那么问题又是什么呢?
额,字符串来回的拼接非常的浪费资源,那么 ,用StringBuilder啊,好接下来继续。
private void TestThreeMethod()
{
StringBuilder querySql = new StringBuilder();
querySql.Append("select * from TestTables");
bool _hasWhere = false;
if (hasOneCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("oneCondition='oneCondition'");
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("twoCondition='twoCondition'");
}
if (hasThreeCondition)
{
_hasWhere = SeachHelper(querySql, _hasWhere);
querySql.Append("threeCondition='threeCondition'");
}
// ....其他条件
// ExcSql(querySql.ToString());
}
等一下,那个公用的方法也得改,当然要改!
private bool SeachHelper(StringBuilder whereString, bool hasWhere)
{
if (!hasWhere)
whereString.Append("where");
else
whereString.Append("and");
return true;
}
上面就是执行动态查询时的逐步优化,说道优化,其实是有一定的前提的,除了第一种情况最低能,其余的要根据实际的情况来进行确定。
如果查询条件非常少,甚至只有两种的情况的时候,则无所谓了,但是如果查询条件越多,那么后面的方法的效率越高。同时对于代码的可读
性越强,想一下,一个项目通常有多少人在写sql查询,如果没给人的风格不同,那么以后的维护人员就要遭罪了,通过使用通用的方法,那么
以后给代码的维护人员带来方便,同时拼接字符串的带来的额外开销也是不容忽视的,好的代码习惯很重要,一个系统从小的地方去注意,那
么最后一定是一个优秀的系统。
Sql动态查询拼接字符串的优化的更多相关文章
- (转)QueryBuilder : 打造优雅的Linq To SQL动态查询
原文地址:http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html 首先我们来看看日常比较典型的一种查询Form 这个 ...
- sql 多条件查询 拼接字符串 改成 普通查询格式
set ANSI_NULLS ON set QUOTED_IDENTIFIER ON go ALTER PROC [dbo].[usp_SRV_CheckServiceDemandOrder] ) = ...
- MYSQL动态查询拼接的表名的SQL脚本实现(MYSQL动态执行SQL脚本)
可以使用MYSQL的预处理逻辑:https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html 例如: pr ...
- SQL动态语句 拼接SQL 并输入输出值
--动态语句语法 /****************************************************************************************** ...
- JPA的动态查询拼接
在使用Spring JPA提供的方法只能进行简单的CRUD,如果遇到复杂的情况就需要我们动态来构建查询条件了.这里我们来看使用CriteriaBuilder如何来构造查询.核心代码: Criteria ...
- sql中用逗号拼接字符串
MSSQL中可以用STUFF函数拼接成字符串. 如: SELECT FieldSomeElse, ( SELECT STUFF(( SELECT ',' + LinkField FROM Detail ...
- SQL STUFF函数 拼接字符串 多列 合并成一列 转
关于和并列的 要这种效果. create table tb(idint, value varchar(10)) insert into tbvalues(1,'aa') insert into tbv ...
- SQL STUFF函数 拼接字符串
今日看到一篇文章,是关于和并列的,也研究了下,还是不错的 要这种效果. create table tb(idint, value varchar(10)) insert into tbvalues(1 ...
- adoquery查询语句sql动态查询删除方法
百度文库链接地址:http://wenku.baidu.com/link?url=uVzbjjaHIziYuproREP_hO7MTLMf2g998QTKN4oLMeko5D7k0vSlTMFaby2 ...
随机推荐
- CentOS BIND9安装及配置
1.安装 #yum install bind 2.备份 named.conf #cp /etc/named.conf /etc/named.conf.bak 3.编辑 named.conf ( ...
- 第42件事 移动App设计的11大法则
移动App设计的重要法则指的是我们在设计App需要遵守的一些设计规范和法则,这些法则就好像一些行为规范一样. 1.导航手机客户端上的主导航(一级导航)如图6-22所示. 对图6-22中所示的几个主导航 ...
- C# 子线程调用主线程窗体的解决方法
摘自其他人博客,自己试过确实解决问题.(如在自己定义的线程里面给textbox赋值) 由于Windows窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value ...
- 怎么把excel表格内的数据导入数据库?
第一种方法: 思路:想要把excel表格内的数据直接导入数据库不是那么容易,可以把excel表格另存为.csv格式的文档(特点:内容以逗号分割):然后通过一系列的文档操作函数处理成为一个二维数组,然后 ...
- 远程连接阿里云服务器出现"远程桌面,身份验证错误:要求的函数不受支持"解决办法
---恢复内容开始--- 更新:win10专业版用户可以看之前的的直接来,但家庭版用户用下面的好像并不能完美解决,献上在网上找到的一个终极解决办法 windows+R打开运行 输入regedit打开 ...
- SQL将原始数据进行MD5加密转存
先来描述下情况吧,首先有一批用户之前批量录入后默认的密码为6个8然后进行MD5加密后进行存储的,现在需要对其更改根据用户身份证号后6位作为密码. 1.首先发现我们sqlserver05以上的版本是自带 ...
- nodejs结合apiblue实现MockServer
apiblue功能很强大,里面支持很多插件,这些插件能够为restfulAPI提供接口文档自动生成,甚至Mockserver的功能,当然,好多插件还是有很多坑的.下面用apiblue实现下面的业务需求 ...
- 【Canal源码分析】数据传输协议
Canal的数据传输有两块,一块是进行binlog订阅时,binlog转换为我们所定义的Message,第二块是client与server进行TCP交互时,传输的TCP协议. 一.EntryProto ...
- php -- 特殊变量的三种输出
----- 020-3outputs.php ----- <!DOCTYPE html> <html> <head> <meta http-equiv=&qu ...
- redis源码学习-dict
1.字典相关的几个结构体 dict由hash table存储key-value, hash table数组每一个元素存放dictEntry链接的链表头结点,dictEntry节点存放key-value ...