[{"data":1,"prerenderedAt":676},["ShallowReactive",2],{"blog:2006:parameterising-the-in-clause-of-an-sql-select-in-net":3,"blogMore-Development":662,"comments-parameterising-the-in-clause-of-an-sql-select-in-net":675},{"id":4,"title":5,"body":6,"category":645,"commentCount":333,"date":646,"description":12,"excerpt":647,"extension":648,"filenames":649,"hidden":650,"image":649,"meta":651,"minutes":265,"navigation":505,"path":652,"seo":653,"showCategory":649,"stem":654,"tags":655,"updated":649,"url":659,"wordCount":660,"__hash__":661},"content\u002Fblog\u002F2006\u002Fparameterising-the-in-clause-of-an-sql-select-in-net.md","Parameterising the IN clause of an SQL SELECT in .NET",{"type":7,"value":8,"toc":640},"minimark",[9,13,18,21,95,98,122,125,157,160,163,180,183,187,190,193,196,200,630,636],[10,11,12],"p",{},"I’m a fan of parameterized queries with a strong dislike for building SQL (or other magic strings). Encoding, escaping errors, localization formatting problems and injection can run rampant when you think everything is a string.",[14,15,17],"h2",{"id":16},"problem","Problem",[10,19,20],{},"Today I found myself a quandary as I needed to SELECT records based on a list of values I had. e.g.",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-sql shiki shiki-themes everforest-light dracula","SELECT * FROM Products WHERE ProductCode IN ('ABC123', 'DEF456', 'GHI789')\n","sql","",[29,30,31],"code",{"__ignoreMap":27},[32,33,36,40,44,47,51,54,57,60,63,67,71,73,76,78,81,83,85,87,90,92],"span",{"class":34,"line":35},"line",1,[32,37,39],{"class":38},"smiwp","SELECT",[32,41,43],{"class":42},"s9HRq"," *",[32,45,46],{"class":38}," FROM",[32,48,50],{"class":49},"s6Vpi"," Products ",[32,52,53],{"class":38},"WHERE",[32,55,56],{"class":49}," ProductCode ",[32,58,59],{"class":38},"IN",[32,61,62],{"class":49}," (",[32,64,66],{"class":65},"sciFF","'",[32,68,70],{"class":69},"sJQOs","ABC123",[32,72,66],{"class":65},[32,74,75],{"class":49},", ",[32,77,66],{"class":65},[32,79,80],{"class":69},"DEF456",[32,82,66],{"class":65},[32,84,75],{"class":49},[32,86,66],{"class":65},[32,88,89],{"class":69},"GHI789",[32,91,66],{"class":65},[32,93,94],{"class":49},")\n",[10,96,97],{},"At first glance the relevant parameterized version might look like:",[22,99,101],{"className":24,"code":100,"language":26,"meta":27,"style":27},"SELECT * FROM Products WHERE ProductCode IN (@productlist)\n",[29,102,103],{"__ignoreMap":27},[32,104,105,107,109,111,113,115,117,119],{"class":34,"line":35},[32,106,39],{"class":38},[32,108,43],{"class":42},[32,110,46],{"class":38},[32,112,50],{"class":49},[32,114,53],{"class":38},[32,116,56],{"class":49},[32,118,59],{"class":38},[32,120,121],{"class":49}," (@productlist)\n",[10,123,124],{},"The problem here however is that if you put a comma-separate list of items into a string parameter named @productlist then it sends this to the database server:",[22,126,128],{"className":24,"code":127,"language":26,"meta":27,"style":27},"SELECT * FROM Products WHERE ProductCode IN ('ABC123, DEF456, GHI789')\n",[29,129,130],{"__ignoreMap":27},[32,131,132,134,136,138,140,142,144,146,148,150,153,155],{"class":34,"line":35},[32,133,39],{"class":38},[32,135,43],{"class":42},[32,137,46],{"class":38},[32,139,50],{"class":49},[32,141,53],{"class":38},[32,143,56],{"class":49},[32,145,59],{"class":38},[32,147,62],{"class":49},[32,149,66],{"class":65},[32,151,152],{"class":69},"ABC123, DEF456, GHI789",[32,154,66],{"class":65},[32,156,94],{"class":49},[10,158,159],{},"That’s not what we want at all.",[10,161,162],{},"This hack isn’t pretty and it has some limitations:",[164,165,166,167,166,171,166,174,166,177],"ul",{},"\n  ",[168,169,170],"li",{},"\n    Only works with named parameters\n  ",[168,172,173],{},"\n    Could upset some DB providers that don’t like having command parameters removed or command text modified\n  ",[168,175,176],{},"\n    Parameter name to replace must be totally unique, i.e. not exist as a subset of another parameter name\n  ",[168,178,179],{},"\n    Only preserves the basic IDbCommand declared properties\n  ",[10,181,182],{},"It should however work across DB providers and types.",[14,184,186],{"id":185},"usage","Usage",[10,188,189],{},"The previous example would mean we use exactly the expected parameterized version with @productlist in place.",[10,191,192],{},"Add the parameter as you’d expect but instead of assigning a string\u002Fnumeric to it assign something IEnumerable.",[10,194,195],{},"Finally call this method against the command and parameter before you execute it for the ‘magic’ to happen:",[14,197,199],{"id":198},"the-magic","The ‘magic’",[22,201,205],{"className":202,"code":203,"language":204,"meta":27,"style":27},"language-csharp shiki shiki-themes everforest-light dracula","public void ExpandDbArrayParameter(IDbCommand cmd, IDbDataParameter parameter) {\n  if (parameter.Value is IEnumerable) {\n    int index = 0;\n    StringBuilder newParameterSQL = new StringBuilder();\n    foreach(Object value in (IEnumerable) parameter.Value) {\n      String valueParameterName = String.Format(\"{0}{1}\", parameter.ParameterName, ++index);\n      IDataParameter valueParameter = cmd.CreateParameter();\n      valueParameter.DbType = parameter.DbType;\n      valueParameter.Direction = parameter.Direction;\n      valueParameter.ParameterName = valueParameterName;\n      valueParameter.SourceColumn = parameter.SourceColumn;\n      valueParameter.SourceVersion = parameter.SourceVersion;\n      valueParameter.Value = value;\n      cmd.Parameters.Add(valueParameter);\n\n      if (index == 1)\n        newParameterSQL.Append(valueParameterName);\n      else\n        newParameterSQL.Append(\",\" + valueParameterName);\n      }\n      cmd.Parameters.Remove(parameter);\n      cmd.CommandText = cmd.CommandText.Replace(parameter.ParameterName, newParameterSQL.ToString());\n    }\n}\n","csharp",[29,206,207,242,263,282,302,331,372,391,410,426,438,454,470,482,500,507,524,536,542,564,570,585,618,624],{"__ignoreMap":27},[32,208,209,212,216,220,223,227,231,233,236,239],{"class":34,"line":35},[32,210,211],{"class":42},"public",[32,213,215],{"class":214},"sXAHl"," void",[32,217,219],{"class":218},"sS4Kt"," ExpandDbArrayParameter",[32,221,222],{"class":49},"(",[32,224,226],{"class":225},"snuxY","IDbCommand",[32,228,230],{"class":229},"s7cAX"," cmd",[32,232,75],{"class":49},[32,234,235],{"class":225},"IDbDataParameter",[32,237,238],{"class":229}," parameter",[32,240,241],{"class":49},") {\n",[32,243,245,248,251,255,258,261],{"class":34,"line":244},2,[32,246,247],{"class":38},"  if",[32,249,250],{"class":49}," (parameter.",[32,252,254],{"class":253},"sSKRk","Value",[32,256,257],{"class":38}," is",[32,259,260],{"class":225}," IEnumerable",[32,262,241],{"class":49},[32,264,266,269,272,275,279],{"class":34,"line":265},3,[32,267,268],{"class":214},"    int",[32,270,271],{"class":49}," index ",[32,273,274],{"class":42},"=",[32,276,278],{"class":277},"s3Ipq"," 0",[32,280,281],{"class":49},";\n",[32,283,285,288,291,293,296,299],{"class":34,"line":284},4,[32,286,287],{"class":225},"    StringBuilder",[32,289,290],{"class":49}," newParameterSQL ",[32,292,274],{"class":42},[32,294,295],{"class":38}," new",[32,297,298],{"class":225}," StringBuilder",[32,300,301],{"class":49},"();\n",[32,303,305,308,310,313,316,319,321,324,327,329],{"class":34,"line":304},5,[32,306,307],{"class":38},"    foreach",[32,309,222],{"class":49},[32,311,312],{"class":225},"Object",[32,314,315],{"class":49}," value ",[32,317,318],{"class":38},"in",[32,320,62],{"class":49},[32,322,323],{"class":225},"IEnumerable",[32,325,326],{"class":49},") parameter.",[32,328,254],{"class":253},[32,330,241],{"class":49},[32,332,334,337,340,342,345,348,350,353,356,358,361,364,366,369],{"class":34,"line":333},6,[32,335,336],{"class":225},"      String",[32,338,339],{"class":49}," valueParameterName ",[32,341,274],{"class":42},[32,343,344],{"class":49}," String.",[32,346,347],{"class":218},"Format",[32,349,222],{"class":49},[32,351,352],{"class":65},"\"",[32,354,355],{"class":69},"{0}{1}",[32,357,352],{"class":65},[32,359,360],{"class":49},", parameter.",[32,362,363],{"class":253},"ParameterName",[32,365,75],{"class":49},[32,367,368],{"class":42},"++",[32,370,371],{"class":49},"index);\n",[32,373,375,378,381,383,386,389],{"class":34,"line":374},7,[32,376,377],{"class":225},"      IDataParameter",[32,379,380],{"class":49}," valueParameter ",[32,382,274],{"class":42},[32,384,385],{"class":49}," cmd.",[32,387,388],{"class":218},"CreateParameter",[32,390,301],{"class":49},[32,392,394,397,400,403,406,408],{"class":34,"line":393},8,[32,395,396],{"class":49},"      valueParameter.",[32,398,399],{"class":253},"DbType",[32,401,402],{"class":42}," =",[32,404,405],{"class":49}," parameter.",[32,407,399],{"class":253},[32,409,281],{"class":49},[32,411,413,415,418,420,422,424],{"class":34,"line":412},9,[32,414,396],{"class":49},[32,416,417],{"class":253},"Direction",[32,419,402],{"class":42},[32,421,405],{"class":49},[32,423,417],{"class":253},[32,425,281],{"class":49},[32,427,429,431,433,435],{"class":34,"line":428},10,[32,430,396],{"class":49},[32,432,363],{"class":253},[32,434,402],{"class":42},[32,436,437],{"class":49}," valueParameterName;\n",[32,439,441,443,446,448,450,452],{"class":34,"line":440},11,[32,442,396],{"class":49},[32,444,445],{"class":253},"SourceColumn",[32,447,402],{"class":42},[32,449,405],{"class":49},[32,451,445],{"class":253},[32,453,281],{"class":49},[32,455,457,459,462,464,466,468],{"class":34,"line":456},12,[32,458,396],{"class":49},[32,460,461],{"class":253},"SourceVersion",[32,463,402],{"class":42},[32,465,405],{"class":49},[32,467,461],{"class":253},[32,469,281],{"class":49},[32,471,473,475,477,479],{"class":34,"line":472},13,[32,474,396],{"class":49},[32,476,254],{"class":253},[32,478,402],{"class":42},[32,480,481],{"class":49}," value;\n",[32,483,485,488,491,494,497],{"class":34,"line":484},14,[32,486,487],{"class":49},"      cmd.",[32,489,490],{"class":253},"Parameters",[32,492,493],{"class":49},".",[32,495,496],{"class":218},"Add",[32,498,499],{"class":49},"(valueParameter);\n",[32,501,503],{"class":34,"line":502},15,[32,504,506],{"emptyLinePlaceholder":505},true,"\n",[32,508,510,513,516,519,522],{"class":34,"line":509},16,[32,511,512],{"class":38},"      if",[32,514,515],{"class":49}," (index ",[32,517,518],{"class":42},"==",[32,520,521],{"class":277}," 1",[32,523,94],{"class":49},[32,525,527,530,533],{"class":34,"line":526},17,[32,528,529],{"class":49},"        newParameterSQL.",[32,531,532],{"class":218},"Append",[32,534,535],{"class":49},"(valueParameterName);\n",[32,537,539],{"class":34,"line":538},18,[32,540,541],{"class":38},"      else\n",[32,543,545,547,549,551,553,556,558,561],{"class":34,"line":544},19,[32,546,529],{"class":49},[32,548,532],{"class":218},[32,550,222],{"class":49},[32,552,352],{"class":65},[32,554,555],{"class":69},",",[32,557,352],{"class":65},[32,559,560],{"class":42}," +",[32,562,563],{"class":49}," valueParameterName);\n",[32,565,567],{"class":34,"line":566},20,[32,568,569],{"class":49},"      }\n",[32,571,573,575,577,579,582],{"class":34,"line":572},21,[32,574,487],{"class":49},[32,576,490],{"class":253},[32,578,493],{"class":49},[32,580,581],{"class":218},"Remove",[32,583,584],{"class":49},"(parameter);\n",[32,586,588,590,593,595,597,599,601,604,607,609,612,615],{"class":34,"line":587},22,[32,589,487],{"class":49},[32,591,592],{"class":253},"CommandText",[32,594,402],{"class":42},[32,596,385],{"class":49},[32,598,592],{"class":253},[32,600,493],{"class":49},[32,602,603],{"class":218},"Replace",[32,605,606],{"class":49},"(parameter.",[32,608,363],{"class":253},[32,610,611],{"class":49},", newParameterSQL.",[32,613,614],{"class":218},"ToString",[32,616,617],{"class":49},"());\n",[32,619,621],{"class":34,"line":620},23,[32,622,623],{"class":49},"    }\n",[32,625,627],{"class":34,"line":626},24,[32,628,629],{"class":49},"}\n",[10,631,632],{},[633,634,635],"em",{},"[)amien",[637,638,639],"style",{},"html pre.shiki code .smiwp, html code.shiki .smiwp{--shiki-default:#F85552;--shiki-dark:#FF79C6}html pre.shiki code .s9HRq, html code.shiki .s9HRq{--shiki-default:#F57D26;--shiki-dark:#FF79C6}html pre.shiki code .s6Vpi, html code.shiki .s6Vpi{--shiki-default:#5C6A72;--shiki-dark:#F8F8F2}html pre.shiki code .sciFF, html code.shiki .sciFF{--shiki-default:#8DA101;--shiki-dark:#E9F284}html pre.shiki code .sJQOs, html code.shiki .sJQOs{--shiki-default:#8DA101;--shiki-dark:#F1FA8C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sXAHl, html code.shiki .sXAHl{--shiki-default:#3A94C5;--shiki-dark:#FF79C6}html pre.shiki code .sS4Kt, html code.shiki .sS4Kt{--shiki-default:#8DA101;--shiki-dark:#50FA7B}html pre.shiki code .snuxY, html code.shiki .snuxY{--shiki-default:#3A94C5;--shiki-default-font-style:inherit;--shiki-dark:#8BE9FD;--shiki-dark-font-style:italic}html pre.shiki code .s7cAX, html code.shiki .s7cAX{--shiki-default:#5C6A72;--shiki-default-font-style:inherit;--shiki-dark:#FFB86C;--shiki-dark-font-style:italic}html pre.shiki code .sSKRk, html code.shiki .sSKRk{--shiki-default:#35A77C;--shiki-dark:#F8F8F2}html pre.shiki code .s3Ipq, html code.shiki .s3Ipq{--shiki-default:#DF69BA;--shiki-dark:#BD93F9}",{"title":27,"searchDepth":244,"depth":244,"links":641},[642,643,644],{"id":16,"depth":244,"text":17},{"id":185,"depth":244,"text":186},{"id":198,"depth":244,"text":199},"Development","2006-10-25T17:36:30+00:00","[object Object]","md",null,false,{},"\u002Fblog\u002F2006\u002Fparameterising-the-in-clause-of-an-sql-select-in-net",{"title":5,"description":12},"blog\u002F2006\u002Fparameterising-the-in-clause-of-an-sql-select-in-net",[656,657,658],".NET","SQL","C#","\u002Fblog\u002F2006\u002Fparameterising-the-in-clause-of-an-sql-select-in-net\u002F",501,"0lC-ZwMOjfHgRURBCZ9pRPZ-V-RkSXkcNJGoAukkAY8",[663,667,671],{"title":664,"date":665,"url":666},"Transactions in the MongoDB EF Core Provider","2025-10-25","\u002Fblog\u002F2025\u002Fmongodb-explicit-transactions\u002F",{"title":668,"date":669,"url":670},"Queryable Encryption with the MongoDB EF Core Provider","2025-09-22","\u002Fblog\u002F2025\u002Fmongodb-queryable-encryption\u002F",{"title":672,"date":673,"url":674},"Lazy Loading with EF Core Proxies","2025-04-02","\u002Fblog\u002F2025\u002Fef-proxies\u002F",[],1780900532589]