(记录)mysql分页查询,参数化过程的坑
在最近的工作中,由于历史遗留,一个分页查询没有参数化,被查出来有sql注入危险,所以对这个查询进行了参数化修改。
一看不知道,看了吓一跳,可能由于种种原因,分页查询sql是在存储过程中拼接出来的,where之后的条件也是在代码中先进行拼接,然后作为整体参数在传入存储过程里,在存入过程里又进行一次拼接。这样的话就有sql注入的潜在危险,尽管在拼接where之前进行的查询条件的验证。
大家都明白,参数化是防止sql注入的有效方法,然后就对这个分页查询进行大刀阔斧的改革。
思路一:1、对原先的代码中拼接的where条件,不进行直接的赋值拼接。而是拼接成带@符号的参数。并且给参数赋值;例如:
if (Num > )
{
sbWhere.Append(" AND s.SysNo=").Append(Num.Value);
}
改
if (Num > )
{
sbWhere.Append(" AND s.SysNo = @SysNo ");
paras.Add(new MySqlParameter("@SysNo", Num.Value));
}
2、给存储过程添加参数
3、用SetParameters(paras.ToArray())方法直接把参数paras传给存储过程
结论:根本走不通,因为我们的查询条件是动态拼接的,没办法动态给存储过程定义传入参数,这个思路直接给pass掉了;
小结:虽然这个方法走不通,但是在这个思路的第一步,是我们可以继续用的,这个是没有问题的。既然没有办法动态定义存储过程参数,我们就不能再存储过程中拼接分页sql,只能把分页sql的select和table、order都放到代码程序中进行拼接,那么我们的思路二就来了。
思路二:1、接着我们思路一第一步之后的往下走
2、代码中拼接分页查询sql;看代码如下:
pagesb.AppendFormat("SELECT {0} from {1} where 1=1 {2} order by {3} limit (@pageNum - 1) * @pageSize,@pageSize;",
selectField, tableName, whereSql, orderField);
结论:还是走不通啊啊啊啊啊啊!从错误日志中查看(@pageNum - 1) * @pageSize,@pageSize这些值都已经传入了,但是就是报错;内容如下:Message: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(1-1)*20, 20' at line 12.
最后发现limit(,) 函数参数内不能进行计算,只能传入值,并且是int类型。
小结:我们就把(@pageNum - 1) * @pageSize的计算放到了代码中。最后代码如下:
int pageindex = (pageNum - ) * pageSize;
paras.Add(new MySqlParameter("@pageSize", pageSize));
paras.Add(new MySqlParameter("@pageindex", pageindex));
StringBuilder pagesb = new StringBuilder();
pagesb.AppendFormat("SELECT {0} from {1} where 1=1 {2} order by {3} limit @pageindex,@pageSize;",
selectField, tableName, whereSql, orderField);
这样我已经成功了一半,为什么说成功了一半呢?因为有些查询条件出现了问题,像模糊查询,怎么都查不出来数据,即时你输入的查询条件是可用的。费了九牛二虎之力找到了问题所在,我们的模糊查询尽管改成了参数化,但是我们把@XXX参数没替换成他对应的值,因为@XXX变成了一个字符串了代码如下:
if (!string.IsNullOrEmpty(Contact))
{
sbWhere.AppendFormat(" AND s.Contact LIKE '%{0}%'", @Contact");
paras.Add(new MySqlParameter("@Contact", Contact));
}
这个问题我们用mysql的CONCAT()函数进行处理,改之后代码如下:
if (!string.IsNullOrEmpty(Contact))
{
sbWhere.AppendFormat(" AND s.Contact LIKE CONCAT('%',{0},'%')", "@Contact");
paras.Add(new MySqlParameter("@Contact", Contact));
}
这样我们就大功告成了。虽然性能上差了很多,但是这个主要是对参数化进行的更改,其中limit(,) 和CONCAT() 函数的使用比较重要。
再有就是本人也是初次接触mysql,许多东西还需要学习。再有就是在给大家提个醒,关于IN() 函数的使用,如果有多个值1,2,3参数化类型会是string,替换值的时候会给‘1,2,3‘ 带上单引号,自然也就找不到你需要的数据了,所以还是用or 慢慢去拼接吧。
郑重声明:本博客,只是为了参数化,性能方面没有过多的考虑。如有错误之处请大家海涵,望多多给予指点。
(记录)mysql分页查询,参数化过程的坑的更多相关文章
- .NET平台开源项目速览(7)关于NoSQL数据库LiteDB的分页查询解决过程
在文章:这些.NET开源项目你知道吗?让.NET开源来得更加猛烈些吧!(第二辑) 与 .NET平台开源项目速览(3)小巧轻量级NoSQL文件数据库LiteDB中,介绍了LiteDB的基本使用情况以及部 ...
- MySQL分页查询limit踩坑记
1 问题背景 线上有一个批处理任务,会批量读取昨日的数据,经过一系列加工后,插入到今日的表中.表结构如下: 1 CREATE TABLE `detail_yyyyMMdd` ( 2 `id` bigi ...
- MySql分页查询慢|这里告诉你答案
一.背景 我们在开发的过程中使用分页是不可避免的,通常情况下我们的做法是使用limit加偏移量:select * from table where column=xxx order by xxx li ...
- mysql 分页查询
mysql,; : mysql,; -last. //如果只给定一个参数,它表示返回最大的记录行数目: mysql; 个记录行 ,n. 动态传参的分页查询 SELECT * FROM table LI ...
- mysql分页查询详解
我们做的后端项目一般都会有admin管理端,当管理端将要展示数据的时候,就需要用到分页.所以分页的考查在面试中也相当多.在mysql中进行分页查询时,一般会使用limit查询,而且通常查询中都会使用o ...
- MySQL分页查询性能优化
当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...
- MySQL分页查询大数据量优化方法
方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...
- mysql分页查询语法
一.limit语法 SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指 ...
- 使用聚集索引和非聚集索引对MySQL分页查询的优化
内容摘录来源:MSSQL123 ,lujun9972.github.io/blog/2018/03/13/如何编写bash-completion-script/ 一.先公布下结论: 1.如果分页排序字 ...
随机推荐
- UVA 10106 Product (大数相乘)
Product The Problem The problem is to multiply two integers X, Y. (0<=X,Y<10250) The Input The ...
- hprof教程 分类: B1_JAVA 2015-03-02 12:18 444人阅读 评论(0) 收藏
大部分内容参考http://www.linuxidc.com/Linux/2012-04/58178.htm J2SE中提供了一个简单的命令行工具来对java程序的cpu和heap进行 profili ...
- hadoop容灾能力测试 分类: A1_HADOOP 2015-03-02 09:38 291人阅读 评论(0) 收藏
实验简单来讲就是 1. put 一个600M文件,分散3个replica x 9个block 共18个blocks到4个datanode 2. 我关掉了两个datanode,使得大部分的block只在 ...
- JAVA学习路线图---(JAVA1234) 分类: B1_JAVA 2013-10-05 10:22 502人阅读 评论(1) 收藏
转自:http://blog.csdn.net/pplcheer/article/details/12276999 第一阶段-Java基础 这一阶段很重要,关系到你后面阶段的学习,所以务 ...
- 体验ArcGIS9.2的历史库功能
转自原文 体验ArcGIS9.2的历史库功能 ESRI公司于2006年11月9日全球同步发布了历史上重要的软件版本ArcGIS9.2,在该版本中,主要新增了以下四大功能(ESRI田昌莲): 第一大新功 ...
- Xmem
http://blog.csdn.net/jthink_/article/details/43302615
- ArcEngine 图层标注 (根据字段、角度)
转自chanyinhelv原文 ArcEngine 图层标注 (根据字段.角度) 今天做了一个用AE来控制图层是否显示标注,以及已哪一个字段作为标注的字段,以哪一个字段作为标注的角度,现将代码写下来, ...
- 在nginx中使用lua直接訪问mysql和memcaced达到数据接口的统一
安装nginx參见<nginx+lua+redis构建高并发应用> 让nginx 中的nginx_lua_module支持mysql 和memcache 下载 https://github ...
- 教你如何利用php.exe运行php文件
教你如何利用php.exe运行php文件 一.总结 一句话总结:就是使用的php.exe,和java中的javac一样,都是有exe,然后有了对应命令,比如php.exe,然后就可以用php命令. 1 ...
- 解决ThinkPad x1 发热的问题
F1进入BIOS界面 将intel speedstep设置为禁用 将CPU Power Manager设置为禁用 重启电脑 电脑不再发热