Оператор SQL SELECT - несколько идентификаторов в предложении IN
Возможный дубликат:
Параметризация предложения SQL IN?
Время от времени я работаю в системе, которая позволяет пользователю выбирать несколько элементов, а затем выполнять массовые действия с ними. Обычно я прибегал к сборке SQL во время выполнения, примерно так:
string inClause = String.Join(", ", selectedIds);
string command = "SELECT * FROM Customer WHERE CustomerId IN ({0})";
command = String.Format(command, inClause);
Конечно, этот стиль кода небезопасен из-за внедрения SQL. Я мог бы решить это, поместив заполнители параметров и создав параметры.
Тем не менее, мне интересно, есть ли другой подход, который я просто не рассматривал. Я, конечно, не хочу выполнять команду один раз для каждого идентификатора.
2 ответа
Есть два хороших подхода:
- Создайте строку с помощью заполнителей команд (как вы сказали)
- Присоединяйтесь к ценностям TVP
Запись идентификаторов в SQL не годится, потому что предотвращает кэширование планов и открывает возможности для внедрения.
Вы можете создать строку XML и затем передать ее в сохраненный процесс. Выполнение это будет выглядеть так:
EXECUTE getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>'
Сохраненный процесс будет выглядеть примерно так:
create proc [dbo].[getLocationTypes](@locationIds XML)
as
begin
set nocount on
SELECT locationId, typeId
FROM xrefLocationTypes
WHERE locationId
IN (SELECT Item.value('.', 'int' )
FROM @locationIDs.nodes('IDList/ID') AS x(Item))
ORDER BY 1, 2
end
Обратите внимание, что тип данных параметра - XML. Это немного сложнее, чем то, что вы делаете, думаю, вы можете сделать все это в одной строке SQL.