использование sqlcommand с несколькими идентификаторами

Итак, это отлично работает:

select name from users where id = @id

Однако это выбирает только 1 парня. Скажем, вместо этого у меня есть 3 идентификатора, обычно SQL будет выглядеть примерно так (без использования параметров)

select name from users where id in (4,6,9)

Однако, похоже, это не работает, когда я пишу

select name from users where id in (@IDs)

и вставьте список в @IDs, как это

cmd.Parameters.AddWithValue("@IDs", userIDs);

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


person Hejner    schedule 27.11.2013    source источник
comment
У вас есть контроль над хранимой процедурой?   -  person AllenG    schedule 27.11.2013
comment
Это еще не сделано, так что да, я делаю.   -  person Hejner    schedule 27.11.2013
comment
Вы можете использовать параметр табличного значения (msdn.microsoft .com/en-us/library/bb675163(v=vs.110).aspx)   -  person meziantou    schedule 27.11.2013
comment
Тогда что сказал @Hejner. Вы можете увидеть пример в ответе на этот вопрос: .com/questions/337704/   -  person AllenG    schedule 27.11.2013
comment
Создайте временную таблицу, вставьте идентификаторы и присоедините ее к таблице с идентификаторами. С большим количеством идентификаторов вы столкнетесь с ограничениями.   -  person Jon Raynor    schedule 27.11.2013


Ответы (3)


Есть два способа сделать это. Первый заключается в передаче строки в хранимую процедуру и последующем добавлении ее в динамический запрос:

-- @IDs  = '4,6,9'
DECLARE @MyQuery nvarchar(max) 
SET @MyQuery = N'SELECT name FROM users WHERE id IN (' + @IDs + ')'
EXEC(@MyQuery)

С другой стороны, если вы используете SQL Server 2008 или более позднюю версию, вы можете использовать параметр с табличным значением (это мое предпочтение).

Сначала создайте пользовательский тип таблицы:

CREATE TYPE IDList AS TABLE (
  id int
)

ТОГДА используйте определенный пользователем тип в качестве типа для вашего параметра:

DECLARE @IDs IDList 
INSERT INTO @IDs (ID) VALUES (4),(6),(9)
SELECT name FROM users u INNER JOIN @IDs i WHERE u.id = i.id  

Если вы используете .NET для использования хранимой процедуры, вы можете найти пример кода для определяемых пользователем типов SQL в MSDN.

person outis nihil    schedule 27.11.2013
comment
если вы передаете «4,6,9», это не сработает, поскольку оно должно выглядеть как IN ('4','6','9') - person Tsukasa; 27.11.2013
comment
Цукаса - Если тип данных идентификатора является строкой, вам нужно ('4', '6', '9'); но если вы посмотрите на его первоначальный вопрос, станет ясно, что тип данных - int или какой-то другой числовой тип, так что нет. - person outis nihil; 27.11.2013
comment
Похоже, что запрос на выполнение - это то, что нужно, к сожалению, мой босс не обновил наш сервер sql. У него так много недостатков, которых нет у обычного запроса. - person Hejner; 27.11.2013

Вы можете создать динамический SQL-запрос внутри вашей хранимой процедуры:

DECLARE @SQLQuery AS NVARCHAR(500)

SET @SQLQuery = 'select name from users where id in ( ' + @userIDs + ')'

EXECUTE(@SQLQuery)

Вы должны быть осторожны и дезинфицировать содержимое @userID, чтобы предотвратить атаки SQL-инъекций.

person System Down    schedule 27.11.2013

Со своей стороны мы используем iBatis.Net для управления этим. Выполнение запроса звучит довольно уродливо, но все же помогает.

В основном мы использовали разделение строк в SQL. См. [question]Как разделить строку, чтобы получить доступ к элементу x?

person dolomitt    schedule 27.11.2013