在最近的工作中,由于检测到一个寻呼查询没有参数化,存在注入sql的危险,因此将此查询参数化并进行了修改。
我不知道。 看了吓了我一跳。 由于各种原因,寻呼查询sql可能在存储过程中被缝合了。 where之后的条件也先在代码中缝合,然后作为整体参数传递到存储中,在存储中再次缝合。 这样,尽管在拼接where之前进行了查询条件验证,但仍存在潜在的sql注入危险。
众所周知,参数化是防止sql注入的有效方法,然后对这个寻呼查询进行重大改革。
想法1 ) 1、对于用原代码连接的where条件,不进行直接的代入连接。 拼接成带@符号的参数。 为参数赋值,例如:
是if (数字0 )
{
SBwhere.append(ands.sysno=) ).append ) num.value );
}
更改if(num0)
{
sb where.append (ands.sys no=@ sys no );
paras.add (newmysqlparameter (' @ sys no ',Num.Value ) );
}
2、向存储过程添加参数
3、setparameters(paras.toarray ) ) ) )方法中将参数paras直接传递给存储过程
结论:根本行不通。 因为我们的查询条件是动态拼接的,所以不能动态定义输入到存储过程中的参数,这种想法直接落到了pass上。
总结:这种方法行不通,但这种思路的第一步,我们可以继续使用。 这没有问题。 由于没有动态定义存储过程参数的方法,因此无法在存储过程中缝合分页sql。 只能把寻呼sql的select、table、order放入代码程序进行拼接。 那么,想法2就来了。
思路2:1、紧跟我们思路的第一步,走下一步
2、代码中拼接寻呼查询sql; 查看代码时,您将看到以下内容:
pagesb.append format (select (from )1) where1=1) orderby )3) limit ) @pagenum-1 ) @pageSize,@pageSize,
selectField,tableName,whereSql,orderField;
结论:果然去不了啊。 啊,啊! 错误日志中所有值(@pageNum - 1 ) @pageSize,@pageSize )都已传递,但报告了错误; 内容: message : youhaveanerrorinyoursqlsyntax; checkthemanualthatcorrespondstoyourmysqlserversionfortherightsyntaxtousenear ' (1-1) * 20,20 ' at line 12。
最后,您发现无法在limit (,)函数参数中进行计算,只能传递值,并且是int类型。
总结:我们把(@pageNum - 1 ) * @pageSize的计算放入了代码中。 最后的代码如下所示。
intpageindex=(pagenum-1 ) *pageSize;
paras.add (newmysqlparameter (' @ pagesize ',pagesize ) );
paras.add (newmysqlparameter (' @ pageindex ',page index );
stringbuilderpagesb=new stringbuilder (;
pagesb.append format (select (from )1) where1=1) orderby )3) limit@pageindex,@pageSize; ) )。
selectField,tableName,whereSql,orderField;
这样我就成功了一半。 为什么可以说成功了一半呢? 因为某些查询条件有问题,所以像模糊查询一样,无论如何都无法查询数据。 您可以使用立即输入的查询条件。 辛苦地发现了问题。 我们的模糊查询已更改为参数化,但没有将@XXX参数替换为其他相应的值。 因为@XXX变成了字符串,所以代码应该如下所示。
if (! string.isnullorempty(contact ) )
{
sb where.append format (ands.contact like ' % {0} % ',@Contact ' );
paras.add (newmysqlparameter (' @ contact ',contact ) );
}
这个问题在mysql的CONCAT ()函数中处理。 更改后的代码如下所示。
if (! string.isnullorempty(contact ) )
{
sb where.append format (ands.contactlikeconcat )、{0}、)、(% )、) @Contact );
paras.add (newmysqlparameter (' @ contact ',contact ) );
}
这样我们就完成了。 虽然性能差很多,但这主要是对参数化进行的更改,其中limit (,) (函数和CONCAT ) )函数的使用很重要。
而且本人也是第一次接触mysql,需要学习很多东西。 进而,IN ) )函数的使用,在有多个值1、2、3参数化类型的情况下为string,置换值时即使加上‘1、2、3’的单引号,也找不到需要的数据,所以用or慢慢地连接
郑重声明:这个博客只是为了参数化,在性能方面很少考虑。 如果有错误,请海涵。 请多加指出。