Это работает для SQL Server 2005 (и более поздних версий):
create procedure IGetAListOfValues
@Ids xml -- This will recevie a List of values
as
begin
-- You can load then in a temp table or use it as a subquery:
create table #Ids (Id int);
INSERT INTO #Ids
SELECT DISTINCT params.p.value('.','int')
FROM @Ids.nodes('/params/p') as params(p);
...
end
Вы должны вызвать эту процедуру с параметром, подобным следующему:
exec IGetAListOfValues
@Ids = '<params> <p>1</p> <p>2</p> </params>' -- xml parameter
Функция node использует xPathвыражение.В данном случае это /params/p
, и поэтому XML использует <params>
в качестве корня и <p>
в качестве элемента.
Функция значения преобразует текст внутри каждого элемента p
в int, но выможет использовать его с другими типами данных легко.В этом примере есть DISTINCT, чтобы избежать повторяющихся значений, но, конечно, вы можете удалить его в зависимости от того, чего вы хотите достичь.
У меня есть вспомогательный (дополнительный) метод, который преобразует IEnumerable<T>
встрока, похожая на ту, что показана в примере выполнения.Его легко создать, и он сделает всю работу за вас, когда вам это нужно.(Вы должны проверить тип данных T и преобразовать в адекватную строку, которая может быть проанализирована на стороне SQL Server).Таким образом, ваш код C # становится чище, а ваши SP следуют той же схеме для получения параметров (вы можете передать столько списков, сколько необходимо).
Одним из преимуществ является то, что вам не нужно делать ничего особенного вваша база данных, чтобы она работала.
Конечно, вам не нужно создавать временную таблицу, как это сделано в моем примере, но вы можете использовать запрос непосредственно как подзапрос внутри предиката IN
1021 *
WHERE MyTableId IN (SELECT DISTINCT params.p.value('.','int')
FROM @Ids.nodes('/params/p') as params(p) )