SqlHelper中IN集合场景下的参数处理
我手头有个古老的项目,持久层用的是古老的ADO.net。前两天去昆明旅游,其中的一个景点是云南民族村,通过导游介绍知道了一个古老的民族——基诺族,“基”在这个族内代表舅舅,“基诺”意为“跟在舅舅后边”,加以引申即为“尊崇舅舅的民族”,很有意思吧,这是我国最后一个被发现并确认下来的少数民族,即第56个民族。 项目里的ado.net和基诺族一样古老。
话说,项目里数据访问层,好多都是拼的sql,这给sql注入提供了可乘之机,为了系统安全,决定在有限的时间内,将它改成参数化。
其中,有个根据多个订单号查询支付单的方法,签名如下:
public DataTable GetAlipayNotifyRecords(AlipayPaymentStatus status, params string[] trade_no)
那么,问题来了,因为sql里有in, 而 in(@no)的方式是行不通的。
怎么办呢? 首先想到的是对参数做处理:
public DataTable GetAlipayNotifyRecords(AlipayPaymentStatus status, params string[] trade_no)
{
string sql = @"select * from T_AlipayNotityRecord where trade_status=@trade_status and trade_no in(@trade_no)";
//string inValue = "'" + string.Join("','", trade_no) + "'";//= string.Join(",", trade_no)
string inValue = "";
trade_no.ToList().ForEach(no => inValue += " union all select '" + no+"'");
inValue = inValue.Substring(" union all".Length);
List<SqlParameter> paramList = new List<SqlParameter>()
{
new SqlParameter("@trade_status",status.ToString()),
new SqlParameter("@trade_no",inValue),
};
var ds = SqlHelper.SqlDataSet(ConfigFile.PayCenterConnection, sql, CommandType.Text, paramList.ToArray());
if (ds == null || ds.Tables.Count == )
return null;
return ds.Tables[];
}
经测试,无效。经分析可知,sqlhelper会把你参数值当成字符串,不会对其做转义。所以,不管怎么对参数值处理,都还是一串字符串。
按这样的原理往下想,只能是将单号分开来传递给sql了。那么正好sql的in可以通过如下几种方式等效实现:
- sql里有临时表,可以in一个临时表--这时,可以考虑and trade_no in(select @p1 union all select @p2 union all...)的方式
- 把sql的in集合,转换为一个用or拼接起来的集合---即,and (trade_no=@p1 or trade_no=@p2 or trade_no=@p3 or...)
如下代码是按照后者的思路解决了这个问题:
public DataTable GetAlipayNotifyRecords(AlipayPaymentStatus status, params string[] trade_no)
{
string sql = @"select * from T_AlipayNotityRecord where trade_status=@trade_status and ({0})"; List<SqlParameter> paramList = new List<SqlParameter>()
{
new SqlParameter("@trade_status",status.ToString()),
};
string sql1 = "";
for (int i=;i<trade_no.Length;i++)
{
sql1 += " or trade_no=@no" + i;
paramList.Add(new SqlParameter("@no" + i, trade_no[i]));
}
sql = string.Format(sql, sql1.Substring(" or ".Length)); var ds = SqlHelper.SqlDataSet(ConfigFile.PayCenterConnection, sql, CommandType.Text, paramList.ToArray());
if (ds == null || ds.Tables.Count == )
return null;
return ds.Tables[];
}
【结语】无意中从园子里看到一篇文章,不该活着的SqlHelper和DBHelper,很赞!
-----2016-12-13 09:39:32
【续】方法总比问题多
今天早上刷牙时,灵光一现,对于昨天的方案,不需要通过借助or或union的方式来更改sql的in了,即,可以直接生成如下的sql语句:
select * from T_AlipayNotityRecord where trade_status=@trade_status and trade_no in(@no0,@no1,...)
程序代码在上面的基础上稍做处理:
public DataTable GetAlipayNotifyRecords(AlipayPaymentStatus status, params string[] trade_no)
{
string sql = @"select * from T_AlipayNotityRecord where trade_status=@trade_status and trade_no in({0})"; List<SqlParameter> paramList = new List<SqlParameter>()
{
new SqlParameter("@trade_status",status.ToString()),
};
string sql1 = "";
for (int i = ; i < trade_no.Length; i++)
{
sql1 += ",@no" + i;
paramList.Add(new SqlParameter("@no" + i, trade_no[i]));
}
sql = string.Format(sql, sql1.Substring(",".Length)); var ds = SqlHelper.SqlDataSet(ConfigFile.PayCenterConnection, sql, CommandType.Text, paramList.ToArray());
if (ds == null || ds.Tables.Count == )
return null;
return ds.Tables[];
}
这样子生成的sql就很直观了。比上面方案的还简短。
SqlHelper中IN集合场景下的参数处理的更多相关文章
- Android智能手机中各种音频场景下的audio data path
上一篇文章(Android智能手机上的音频浅析)说本篇将详细讲解Android智能手机中各种音频场景下的音频数据流向,现在我们就开始.智能手机中音频的主要场景有音频播放.音频录制.语音通信等.不同场景 ...
- asp.net core中负载均衡场景下http重定向https的问题
上周欣喜地发现,微软官方终于针对 asp.net core 在使用负载均衡的情况下从 http 强制重定向至 https 的问题提供了解决方法. app.UseForwardedHeaders(new ...
- nginx 自动忽略request中header name包含下划线参数的解决方法
使用nginx过程中遇到了个问题,就是request中的header name中如果包含下划线会自动忽略掉,导致服务器接收不到该字段的内容,以下为解决方法: nginx默认request的header ...
- HBase指定大量列集合的场景下并发拉取数据时卡住的问题排查
最近遇到一例,HBase 指定大量列集合的场景下,并发拉取数据,应用卡住不响应的情形.记录一下. 问题背景 退款导出中,为了获取商品规格编码,需要从 HBase 表 T 里拉取对应的数据. T 对商品 ...
- Loadrunner 运行场景-场景中的全局变量与关联结果参数
运行场景-场景中的全局变量与关联结果参数 by:授客 QQ:1033553122 A. 全局变量 实验1: globals.h #ifndef _GLOBALS_H #define _GLOB ...
- Disruptor框架中生产者、消费者的各种复杂依赖场景下的使用总结
版权声明:原创作品,谢绝转载!否则将追究法律责任. Disruptor是一个优秀的并发框架,可以实现单个或多个生产者生产消息,单个或多个消费者消息,且消费者之间可以存在消费消息的依赖关系.网上其他博客 ...
- ASP.NET MVC中默认Model Binder绑定Action参数为List、Dictionary等集合的实例
在实际的ASP.NET mvc项目开发中,有时会遇到一个参数是一个List.Dictionary等集合类型的情况,默认的情况ASP.NET MVC框架是怎么为我们绑定ASP.NET MVC的Actio ...
- Asp.net MVC中提交集合对象,实现Model绑定
Asp.net MVC中的Model自动绑定功能,方便了我们对于request中的数据的处理, 从客户端的请求数据,自动地以Action方法参数的形式呈现.有时候我们的Action方法中想要接收数组类 ...
- Asp.net MVC中提交集合对象,实现Model绑定(转载)
Asp.net MVC中的Model自动绑定功能,方便了我们对于request中的数据的处理, 从客户端的请求数据,自动地以Action方法参数的形式呈现.有时候我们的Action方法中想要接收数组类 ...
随机推荐
- VisualVM通过jstatd方式远程监控远程主机
配置好权限文件 [root@test bin]# cd $JAVA_HOME/bin [root@test bin]# vim jstatd.all.policy grant codebase &qu ...
- 为什么 NaN 不等于自身?
NaN 即Not a Number , 不是一个数字, 那么NaN到底是什么呢? 话说在JavaScript中,有6大数据类型,分别包括string,number,boolean,undefined, ...
- DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享
DBImport V3.7介绍: 1:先上图,再介绍亮点功能: 主要的升级功能为: 1:增加(Truncate Table)清表再插入功能: 清掉再插,可以保证两个库的数据一致,自己很喜欢这个功能. ...
- TODO:GitHub创建组织的步骤
TODO:GitHub创建组织的步骤 使用GitHub进行团队合作,写这个步骤主要作用是为了OneTODO作为一个团队组织进行代码的分享,让更多人来参与. 使用帐号.密码登录GitHub 2.右上角加 ...
- Linux 开机时网络自动连接
简单版本: cd /etc/sysconfig/network-scripts/ vi ifcfg-enoXXX 输入:reboot重启 或者输入:service network restart ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- 协议森林17 我和你的悄悄话 (SSL/TLS协议)
作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系. TLS名为传输层安全协议(Transport Layer Protocol),这个协议是一套加密的 ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- javascript数组查重方法总结
文章参考地址:http://blog.csdn.net/chengxuyuan20100425/article/details/8497277 题目 对下列数组去重: var arr = ['aa', ...
- C# 实时折线图,波形图
此Demo是采用VS自带的Chart图表控件,制作实时动态显示的折线图,和波形图. 涉及到知识如下: Chart 控件,功能强大,可以绘制柱状图,折线图,波形图,饼状图,大大简化了对图的开发与定制. ...