Параметризованные запросы с условиями 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;
Где:
CategoryIDs
— это строка, содержащая список идентификаторов, разделённых запятыми, например "123,456,789" (без кавычек).Name
— это строка, которая может содержать одинарные кавычки и другие символы, требующие экранирования.
Какова правильная синтаксис для передачи списка идентификаторов и подстановки строки в параметризованном запросе?
2 ответ(ов)
Чтобы использовать символ "%" в значении SQL-параметра, нужно просто сконкатенировать "%" с вашим значением. В приведенном вами коде это уже сделано для параметра @name
, где значение создается следующим образом: comm.Parameters["@name"].Value = "%" + Name + "%";
.
Это гарантирует, что при выполнении SQL-запроса для фильтрации по имени продукта будет осуществляться поиск с учетом подстроки, заключенной между символами "%". Однако стоит убедиться, что переменная Name
не равна null
, чтобы избежать возможных проблем.
Полный код с учетом этого аспекта может выглядеть так:
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.Trim() + "%"; // Trim для удаления лишних пробелов
Таким образом, вы убедитесь, что символы "%" используются корректно в вашем SQL-запросе.
Этот подход не сработает. Точка.
Оператор IN ожидает список параметров, так что когда вы связываете один параметр с ним, у вас есть возможность передать одно значение.
Создайте строку запроса динамически, с точным количеством отдельных заполнителей для оператора IN, которые вы собираетесь использовать, а затем добавьте параметры и свяжите значения с ними в цикле.
Как предотвратить SQL-инъекции в PHP?
SQL-инъекция, обхватывающая mysql_real_escape_string()
Как добавить пользовательский ввод в SQL-запрос?
Как вставить перенос строки в строке VARCHAR/NVARCHAR SQL Server
Выполнение SQL из файла в SQLAlchemy