日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SqlHelper中IN集合场景下的参数处理

發布時間:2025/5/22 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 == 0)return null;return ds.Tables[0]; }

經測試,無效。經分析可知,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=0;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 == 0)return null;return ds.Tables[0]; }

【結語】無意中從園子里看到一篇文章,不該活著的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 = 0; 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 == 0)return null;return ds.Tables[0]; }

這樣子生成的sql就很直觀了。比上面方案的還簡短。

?

轉載于:https://www.cnblogs.com/buguge/p/6165972.html

總結

以上是生活随笔為你收集整理的SqlHelper中IN集合场景下的参数处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。