婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > SqlServer參數(shù)化查詢之where in和like實現(xiàn)詳解

SqlServer參數(shù)化查詢之where in和like實現(xiàn)詳解

熱門標簽:西安青牛防封電銷卡 威海智能語音外呼系統(tǒng) 400電話申請需要開戶費嗎 重慶防封電銷機器人供應商 智能語音外呼系統(tǒng)哪個牌子好 北京辦理400電話多少 山西語音外呼系統(tǒng)價格 南京電銷外呼系統(tǒng)運營商 溫州語音外呼系統(tǒng)代理
身為一名小小的程序猿,在日常開發(fā)中不可以避免的要和where in和like打交道,在大多數(shù)情況下我們傳的參數(shù)不多簡單做下單引號、敏感字符轉義之后就直接拼進了SQL,執(zhí)行查詢,搞定。若有一天你不可避免的需要提高SQL的查詢性能,需要一次性where in 幾百、上千、甚至上萬條數(shù)據(jù)時,參數(shù)化查詢將是必然進行的選擇。然而如何實現(xiàn)where in和like的參數(shù)化查詢,是個讓不少人頭疼的問題。

where in 的參數(shù)化查詢實現(xiàn)

首先說一下我們常用的辦法,直接拼SQL實現(xiàn),一般情況下都能滿足需要
復制代碼 代碼如下:

string userIds = "1,2,3,4";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
comm.CommandText = string.Format("select * from Users(nolock) where UserID in({0})", userIds);
comm.ExecuteNonQuery();
}

需要參數(shù)化查詢時進行的嘗試,很顯然如下這樣執(zhí)行SQL會報錯錯誤
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
comm.CommandText = "select * from Users(nolock) where UserID in(@UserID)";
comm.Parameters.Add(new SqlParameter("@UserID", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });
comm.ExecuteNonQuery();
}

很顯然這樣會報錯誤:在將 varchar 值 '1,2,3,4' 轉換成數(shù)據(jù)類型 int 時失敗,因為參數(shù)類型為字符串,where in時會把@UserID當做一個字符串來處理,相當于實際執(zhí)行了如下語句
復制代碼 代碼如下:

select * from Users(nolock) where UserID in('1,2,3,4')

若執(zhí)行的語句為字符串類型的,SQL執(zhí)行不會報錯,當然也不會查詢出任何結果
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
comm.CommandText = "select * from Users(nolock) where UserName in(@UserName)";
comm.Parameters.Add(new SqlParameter("@UserName", SqlDbType.VarChar, -1) { Value = "'john','dudu','rabbit'" });
comm.ExecuteNonQuery();
}

這樣不會抱任何錯誤,也查不出想要的結果,因為這個@UserName被當做一個字符串來處理,實際相當于執(zhí)行如下語句
復制代碼 代碼如下:

select * from Users(nolock) where UserName in('''john'',''dudu'',''rabbit''')

由此相信大家對于為何簡單的where in 傳參無法得到正確的結果知道為什么了吧,下面我們來看一看如何實現(xiàn)正確的參數(shù)化執(zhí)行where in,為了真正實現(xiàn)參數(shù)化where in 傳參,很多淫才想到了各種替代方案

方案1,使用CHARINDEX或like 方法實現(xiàn)參數(shù)化查詢,毫無疑問,這種方法成功了,而且成功的復用了查詢計劃,但同時也徹底的讓查詢索引失效(在此不探討索引話題),造成的后果是全表掃描,如果表里數(shù)據(jù)量很大,百萬級、千萬級甚至更多,這樣的寫法將造成災難性后果;如果數(shù)據(jù)量比較小、只想借助參數(shù)化實現(xiàn)防止SQL注入的話這樣寫也無可厚非,還是得看具體需求。(不推薦)

復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//使用CHARINDEX,實現(xiàn)參數(shù)化查詢,可以復用查詢計劃,同時會使索引失效
comm.CommandText = "select * from Users(nolock) where CHARINDEX(','+ltrim(str(UserID))+',',','+@UserID+',')>0";
comm.Parameters.Add(new SqlParameter("@UserID", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });
comm.ExecuteNonQuery();
}

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//使用like,實現(xiàn)參數(shù)化查詢,可以復用查詢計劃,同時會使索引失效
comm.CommandText = "select * from Users(nolock) where ','+@UserID+',' like '%,'+ltrim(str(UserID))+',%' ";
comm.Parameters.Add(new SqlParameter("@UserID", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });
comm.ExecuteNonQuery();
}

方案2 使用exec動態(tài)執(zhí)行SQL,這樣的寫法毫無疑問是很成功的,而且代碼也比較優(yōu)雅,也起到了防止SQL注入的作用,看上去很完美,不過這種寫法和直接拼SQL執(zhí)行沒啥實質性的區(qū)別,查詢計劃沒有得到復用,對于性能提升沒任何幫助,頗有種脫了褲子放屁的感覺,但也不失為一種解決方案。(不推薦)
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//使用exec動態(tài)執(zhí)行SQL
  //實際執(zhí)行的查詢計劃為(@UserID varchar(max))select * from Users(nolock) where UserID in (1,2,3,4)
  //不是預期的(@UserID varchar(max))exec('select * from Users(nolock) where UserID in ('+@UserID+')')
comm.CommandText = "exec('select * from Users(nolock) where UserID in ('+@UserID+')')";
comm.Parameters.Add(new SqlParameter("@UserID", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });
comm.ExecuteNonQuery();
}

方案3 為where in的每一個參數(shù)生成一個參數(shù),寫法上比較麻煩些,傳輸?shù)膮?shù)個數(shù)有限制,最多2100個,可以根據(jù)需要使用此方案(推薦)
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//為每一條數(shù)據(jù)添加一個參數(shù)
comm.CommandText = "select * from Users(nolock) where UserID in (@UserID1,@UserId2,@UserID3,@UserID4)";
comm.Parameters.AddRange(
new SqlParameter[]{
new SqlParameter("@UserID1", SqlDbType.Int) { Value = 1},
new SqlParameter("@UserID2", SqlDbType.Int) { Value = 2},
new SqlParameter("@UserID3", SqlDbType.Int) { Value = 3},
new SqlParameter("@UserID4", SqlDbType.Int) { Value = 4}
});

comm.ExecuteNonQuery();
}

方案4 使用臨時表實現(xiàn)(也可以使用表變量性能上可能會更加好些),寫法實現(xiàn)上比較繁瑣些,可以根據(jù)需要寫個通用的where in臨時表查詢的方法,以供不時之需,個人比較推崇這種寫法,能夠使查詢計劃得到復用而且對索引也能有效的利用,不過由于需要創(chuàng)建臨時表,會帶來額外的IO開銷,若查詢頻率很高,每次的數(shù)據(jù)不多時還是建議使用方案3,若查詢數(shù)據(jù)條數(shù)較多,尤其是上千條甚至上萬條時,強烈建議使用此方案,可以帶來巨大的性能提升(強烈推薦)
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
string sql = @"
declare @Temp_Variable varchar(max)
create table #Temp_Table(Item varchar(max))
while(LEN(@Temp_Array) > 0)
begin
if(CHARINDEX(',',@Temp_Array) = 0)
begin
set @Temp_Variable = @Temp_Array
set @Temp_Array = ''
end
else
begin
set @Temp_Variable = LEFT(@Temp_Array,CHARINDEX(',',@Temp_Array)-1)
set @Temp_Array = RIGHT(@Temp_Array,LEN(@Temp_Array)-LEN(@Temp_Variable)-1)
end
insert into #Temp_Table(Item) values(@Temp_Variable)
end
select * from Users(nolock) where exists(select 1 from #Temp_Table(nolock) where #Temp_Table.Item=Users.UserID)
drop table #Temp_Table";
comm.CommandText = sql;
comm.Parameters.Add(new SqlParameter("@Temp_Array", SqlDbType.VarChar, -1) { Value = "1,2,3,4" });
comm.ExecuteNonQuery();
}

like參數(shù)化查詢
like查詢根據(jù)個人習慣將通配符寫到參數(shù)值中或在SQL拼接都可,兩種方法執(zhí)行效果一樣,在此不在詳述
復制代碼 代碼如下:

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//將 % 寫到參數(shù)值中
comm.CommandText = "select * from Users(nolock) where UserName like @UserName";
comm.Parameters.Add(new SqlParameter("@UserName", SqlDbType.VarChar, 200) { Value = "rabbit%" });
comm.ExecuteNonQuery();
}

using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand comm = new SqlCommand();
comm.Connection = conn;
//SQL中拼接 %
comm.CommandText = "select * from Users(nolock) where UserName like @UserName+'%'";
comm.Parameters.Add(new SqlParameter("@UserName", SqlDbType.VarChar, 200) { Value = "rabbit%" });
comm.ExecuteNonQuery();
}

看到Tom.湯和蚊子額的評論 補充了下xml傳參和tvp傳參,并對6種方案做了個簡單總結

Sql Server參數(shù)化查詢之where in和like實現(xiàn)之xml和DataTable傳參

此文章屬懶惰的肥兔原創(chuàng)
您可能感興趣的文章:
  • SQLServer中使用擴展事件獲取Session級別的等待信息及SQLServer 2016中Session級別等待信息的增強
  • sqlserver 模糊查詢常用方法
  • SqlServer使用 case when 解決多條件模糊查詢問題
  • SqlServer中模糊查詢對于特殊字符的處理方法
  • MSSQL Server 查詢優(yōu)化方法 整理
  • sqlserver 中charindex/patindex/like 的比較
  • SqlServer參數(shù)化查詢之where in和like實現(xiàn)之xml和DataTable傳參介紹
  • SqlServer2016模糊匹配的三種方式及效率問題簡析

標簽:新余 金昌 河源 宜春 貸款群呼 黃山 濟寧 中衛(wèi)

巨人網(wǎng)絡通訊聲明:本文標題《SqlServer參數(shù)化查詢之where in和like實現(xiàn)詳解》,本文關鍵詞  SqlServer,參數(shù),化,查詢,之,;如發(fā)現(xiàn)本文內(nèi)容存在版權問題,煩請?zhí)峁┫嚓P信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《SqlServer參數(shù)化查詢之where in和like實現(xiàn)詳解》相關的同類信息!
  • 本頁收集關于SqlServer參數(shù)化查詢之where in和like實現(xiàn)詳解的相關信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    偷拍与自拍一区| 欧美一级爆毛片| 国产一区二区毛片| 日本不卡一区二区三区| 亚洲综合一区在线| 亚洲激情男女视频| 亚洲影院久久精品| 亚洲第一搞黄网站| 婷婷国产在线综合| 丝瓜av网站精品一区二区| 午夜一区二区三区在线观看| 亚洲综合一区在线| 蜜桃久久久久久| 国产在线视频一区二区三区| 国产成人精品亚洲午夜麻豆| a级精品国产片在线观看| 99在线精品观看| 欧美精品色一区二区三区| 欧美一级欧美三级在线观看| 精品国产一区二区三区不卡| 久久久久国产一区二区三区四区| 欧美一区二区三区日韩视频| 日韩久久久精品| 国产精品丝袜91| 亚洲国产精品久久人人爱蜜臀| 久久精品国产澳门| 成人免费视频视频| 在线亚洲+欧美+日本专区| 777a∨成人精品桃花网| 久久综合久久鬼色| 亚洲视频网在线直播| 亚洲成人av免费| 国产成人高清在线| 欧美精品aⅴ在线视频| 国产婷婷色一区二区三区| 亚洲影院免费观看| 成人午夜又粗又硬又大| 欧美日韩一区二区三区高清| 久久九九99视频| 亚洲不卡一区二区三区| 国产成人亚洲综合a∨猫咪| 欧美伊人精品成人久久综合97| 精品国产露脸精彩对白| 亚洲精品日日夜夜| 韩国女主播成人在线| 色国产综合视频| 欧美国产一区二区| 日韩黄色免费电影| 91搞黄在线观看| 国产午夜亚洲精品不卡| 三级久久三级久久| 91免费国产视频网站| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 午夜精品影院在线观看| 国产成人亚洲综合a∨猫咪| 91精品视频网| 亚洲一区影音先锋| eeuss影院一区二区三区| 欧美精品一区二区三区蜜桃视频| 亚洲一区二区三区自拍| 91蜜桃免费观看视频| 国产区在线观看成人精品| 日本不卡一区二区| 欧美疯狂做受xxxx富婆| 亚洲一区精品在线| 一本色道久久综合亚洲91| 国产日韩精品视频一区| 国产一区二区伦理片| 精品久久久久久久久久久院品网 | 高清国产一区二区三区| 欧美成人video| 蜜桃视频在线观看一区| 欧美精品99久久久**| 婷婷中文字幕一区三区| 欧美日韩大陆在线| 亚洲成av人片一区二区三区| 欧美午夜精品一区二区蜜桃| 一区二区激情视频| 91黄色小视频| 午夜伊人狠狠久久| 日韩情涩欧美日韩视频| 日本中文字幕一区二区视频| 欧美色涩在线第一页| 婷婷成人综合网| 欧美一二三区在线观看| 久久成人av少妇免费| 久久人人97超碰com| 国产精品一区在线观看你懂的| 国产欧美日韩麻豆91| 99视频在线精品| 夜夜揉揉日日人人青青一国产精品| 色综合久久天天综合网| 亚洲成人精品在线观看| 日韩欧美卡一卡二| 国产一区三区三区| 国产精品国产三级国产| 精品视频999| 国产一区二区三区四区五区美女 | 亚洲第一会所有码转帖| 欧美一级黄色录像| 国产精品小仙女| 亚洲精品精品亚洲| 日韩欧美一区二区久久婷婷| 国产超碰在线一区| 亚洲图片欧美色图| 久久久久久久久蜜桃| fc2成人免费人成在线观看播放 | 欧美乱妇15p| 国产精品资源在线观看| 亚洲乱码中文字幕| 日韩欧美精品在线视频| 97精品电影院| 国产在线精品免费av| 亚洲三级在线观看| 精品国产百合女同互慰| 色老综合老女人久久久| 午夜成人在线视频| 国产精品系列在线| 欧美一区二区三区系列电影| 国产.欧美.日韩| 日韩不卡一区二区| 亚洲欧洲美洲综合色网| 欧美一级黄色大片| 在线区一区二视频| www.欧美.com| 韩国成人精品a∨在线观看| 亚洲一区二区综合| 国产精品灌醉下药二区| www国产精品av| 欧美色窝79yyyycom| www.欧美日韩国产在线| 国产做a爰片久久毛片| 亚洲一级二级三级| 自拍视频在线观看一区二区| 久久久91精品国产一区二区精品 | 亚洲大尺度视频在线观看| 久久久亚洲精品石原莉奈| 欧美中文字幕久久 | 亚洲电影视频在线| 国产精品久久久久久亚洲伦| 久久在线观看免费| 欧美电影影音先锋| 欧美日韩精品欧美日韩精品| 色婷婷综合久久久久中文| 国产经典欧美精品| 国产福利精品一区二区| 国产自产高清不卡| 国产一区二区三区蝌蚪| 日韩av在线免费观看不卡| 亚洲高清免费视频| 亚洲男同1069视频| 亚洲欧美日韩综合aⅴ视频| 18成人在线视频| 夜夜嗨av一区二区三区| 亚洲综合男人的天堂| 亚洲成av人片一区二区三区| 性感美女极品91精品| 午夜精品爽啪视频| 免费成人性网站| 精品一区中文字幕| 国产精品系列在线观看| 国产成人综合亚洲网站| 成人国产精品免费观看视频| 成人av资源下载| 欧美亚洲一区三区| 日韩无一区二区| 久久久久久久电影| 亚洲色欲色欲www| 亚洲午夜久久久久中文字幕久| 亚洲第一福利视频在线| 蜜臀av一区二区| 成人免费毛片高清视频| 在线观看免费亚洲| 91精品一区二区三区在线观看| 精品国产乱码久久久久久闺蜜| 欧美极品少妇xxxxⅹ高跟鞋 | 制服丝袜亚洲播放| 精品久久久久一区| 国产精品乱码一区二三区小蝌蚪| 亚洲乱码中文字幕综合| 免费看日韩a级影片| 成人午夜激情在线| 欧美日韩高清在线播放| 国产日韩欧美综合在线| 亚洲综合久久av| 国产一区二区三区日韩| 91免费观看国产| 日韩美女视频在线| 一区二区三区精品视频在线| 黄色成人免费在线| 91成人免费在线| 国产日本欧美一区二区| 亚洲综合网站在线观看| 国产精品自在在线| 在线播放日韩导航| 亚洲欧洲性图库| 国产精品一区二区久激情瑜伽| 欧美在线观看视频一区二区| 中文字幕乱码一区二区免费| 日韩电影免费一区|