Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parameterized Queries with LIKE and IN conditions

Parameterized Queries in .Net always look like this in the examples:

SqlCommand comm = new SqlCommand(@"    SELECT *     FROM   Products     WHERE  Category_ID = @categoryid ",     conn); comm.Parameters.Add("@categoryid", SqlDbType.Int); comm.Parameters["@categoryid"].Value = CategoryID; 

But I'm running into a brick wall trying to do the following:

SqlCommand comm = new SqlCommand(@"    SELECT *     FROM   Products     WHERE  Category_ID IN (@categoryids)        OR  name LIKE '%@name%' ",     conn); comm.Parameters.Add("@categoryids", SqlDbType.Int); comm.Parameters["@categoryids"].Value = CategoryIDs; comm.Parameters.Add("@name", SqlDbType.Int); comm.Parameters["@name"].Value = Name; 

Where

  • CategoryIDs is a comma separated list of numbers "123,456,789" (without quotes)
  • Name is a string, possibly with single quotes and other bad characters

What's the right syntax for this?

like image 564
Tom Ritter Avatar asked Nov 19 '08 19:11

Tom Ritter


People also ask

What is parameterized query with example?

A parameterized query is a query in which placeholders are used for parameters and the parameter values are supplied at execution time. The most important reason to use parameterized queries is to avoid SQL injection attacks.

How do I write a parameterized query in SQL?

Declare statements start with the keyword DECLARE , followed by the name of the parameter (starting with a question mark) followed by the type of the parameter and an optional default value. The default value must be a literal value, either STRING , NUMERIC , BOOLEAN , DATE , or TIME .

What is a parameterized query in a SQL statement?

Parameterized SQL queries allow you to place parameters in an SQL query instead of a constant value. A parameter takes a value only when the query is executed, which allows the query to be reused with different values and for different purposes.


2 Answers

Let's say that you have your category ids in an integer array and Name is a string. The trick is to create the command text to allow you to enter all of your category ids as individual parameters and construct the fuzzy match for name. To do the former, we use a loop to construct a sequence of parameter names @p0 through @pN-1 where N is the number of category ids in the array. Then we construct a parameter and add it to the command with the associated category id as the value for each named parameter. Then we use concatenation on the name in the query itself to allow the fuzzy search on name.

string Name = "someone"; int[] categoryIDs = new int[] { 238, 1138, 1615, 1616, 1617,                                 1618, 1619, 1620, 1951, 1952,                                 1953, 1954, 1955, 1972, 2022 };  SqlCommand comm = conn.CreateCommand();  string[] parameters = new string[categoryIDs.Length]; for(int i=0;i<categoryIDs.Length;i++) {    parameters[i] = "@p"+i;    comm.Parameters.AddWithValue(parameters[i], categoryIDs[i]); } comm.Parameters.AddWithValue("@name",$"%{Name}%"); comm.CommandText = "SELECT * FROM Products WHERE Category_ID IN ("; comm.CommandText += string.Join(",", parameters) + ")"; comm.CommandText += " OR name LIKE @name"; 

This is a fully parameterized query that should make your DBA happy. I suspect that since these are integers, though it would not be much of a security risk just to construct the command text directly with the values, while still parameterizing the name. If your category ids are in a string array, just split the array on commas, convert each to an integer, and store it in the integer array.

Note: I say array and use it in the example, but it should work for any collection, although your iteration will probably differ.

Original idea from http://www.tek-tips.com/viewthread.cfm?qid=1502614&page=9

like image 133
tvanfosson Avatar answered Oct 08 '22 22:10

tvanfosson


You need "%" in value of sql parameter.

SqlCommand comm = new SqlCommand("SELECT * FROM Products WHERE Category_ID IN (@categoryid1, @categoryid2) OR name LIKE @name", conn); comm.Parameters.Add("@categoryid1", SqlDbType.Int); comm.Parameters["@categoryid1"].Value = CategoryID[0]; comm.Parameters.Add("@categoryid2", SqlDbType.Int); comm.Parameters["@categoryid2"].Value = CategoryID[1]; comm.Parameters.Add("@name", SqlDbType.NVarChar); comm.Parameters["@name"].Value = "%" + Name + "%"; 
like image 27
TcKs Avatar answered Oct 08 '22 22:10

TcKs