Подтвердить что ты не робот

Параметрированные запросы с условиями LIKE и IN

Параметрированные запросы в .Net всегда выглядят следующим образом:

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

Но я столкнулся с кирпичной стеной, пытаясь сделать следующее:

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;

Где

  • CategoryID - это список номеров, разделенных запятыми "123 456 789" (без кавычек).
  • Имя - это строка, возможно с одинарными кавычками и другими плохими символами.

Какой правильный синтаксис для этого?

4b9b3361

Ответ 1

Скажем, что у вас есть идентификаторы категорий в целочисленном массиве, а Name - строка. Хитрость заключается в создании текста команды, позволяющего вводить все идентификаторы вашей категории в виде отдельных параметров и строить нечеткое соответствие имени. Чтобы сделать первый, мы используем цикл для построения последовательности имен параметров @p0 через @pN-1, где N - количество идентификаторов категории в массиве. Затем мы создаем параметр и добавляем его в команду с ассоциированным идентификатором категории как значение для каждого именованного параметра. Затем мы используем конкатенацию имени в самом запросе, чтобы разрешить нечеткий поиск по имени.

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";

Это полностью параметризованный запрос, который должен сделать ваш администратор базы данных счастливым. Я подозреваю, что, поскольку они являются целыми числами, хотя это не было бы большим риском для безопасности, просто для того, чтобы напрямую строить текст команды со значениями, но все же параметризуя имя. Если идентификаторы категорий находятся в строковом массиве, просто разделите массив на запятые, преобразуйте их в целое число и сохраните в массиве integer.

Примечание: Я говорю массив и использую его в примере, но он должен работать для любой коллекции, хотя ваша итерация, вероятно, будет отличаться.

Оригинальная идея http://www.tek-tips.com/viewthread.cfm?qid=1502614&page=9

Ответ 2

Вам нужно "%" в значении параметра sql.

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.Int);
comm.Parameters["@name"].Value = "%" + Name + "%";

Ответ 3

Этот подход не будет работать. Период.

Предложение IN ожидает список параметров, поэтому, когда вы привязываете к нему один параметр, вы можете передать одно значение.

Стройте свою строку оператора динамически, с точной суммой отдельных закладок, которые вы намерены передать, а затем добавьте параметры и привяжите значения к ним в цикле.

Ответ 4

не уверен, что это правильный путь, но это способ, которым я это сделал в разделе "До

list templist = новый список

comm.Parameters.Add( "@categoryids", SqlDbType.varchar); comm.Parameters [ "@categoryids" ]. value = string.join( ",", templist.toarray())