Создание таблицы SQL из объединенного списка через запятую - PullRequest
3 голосов
/ 18 августа 2010

Я использую SQL Server и у меня есть хранимая процедура. Я хочу сделать оператор выбора с предложением WHERE IN. Я не знаю, как долго этот список будет таким, сейчас я попробовал что-то следующее

SELECT * FROM table1 WHERE id IN (@idList)

в этом решении @idList - это varChar (max). но это не работает Я слышал о передаче значений в таблице, но я не уверен, как это сделать. Любая помощь будет великолепна

Ответы [ 5 ]

2 голосов
/ 18 августа 2010

Я бы предложил использовать функцию для разделения входящего списка (используйте ссылку , которую Мартин поместил в своем комментарии).

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

select * into #ids from dbo.Split(',', @idList)

select t.*
from table1 t
 join #ids i
    on t.id = i.s
2 голосов
/ 18 августа 2010

Самый эффективный способ - передать параметр с табличным значением (если вы используете SQL Server 2008) или параметр XML (если вы используете SQL Server 2005/2000).Если ваш список небольшой (и вы используете SQL Server 2005/2000), передача его в виде списка с разделителями-запятыми (или иным образом) и использование функции разделения для разделения значений на строки во временной таблице также являетсяoption.

Какой бы вариант вы ни использовали, вы затем присоедините эту таблицу (либо параметр таблицы, таблицу, полученную в результате выбора XML, либо временную таблицу, созданную значениями из разделения) к вашему основному запросу.

1 голос
/ 19 августа 2010

Вот табличная функция, которая принимает nvarchar и возвращает таблицу для присоединения:

Create function [ReturnValues]
(
@Values nvarchar(4000)
)
Returns @ValueTable table(Value nvarchar(2000))
As
Begin
Declare @Start int
Declare @End int
Set @Start = 1
Set @End = 1

While @Start <= len(@Values)
Begin
      Set @End = charindex(',', @Values, @Start)
      If @End = 0
            Set @End = len(@Values) + 1
      Insert into @ValueTable
      Select rtrim(ltrim(substring(@Values, @Start, @End - @Start)))
      Set @Start = @End + 1
End
Return
End

GO
0 голосов
/ 18 августа 2010

Привязка параметра @idList, как вы предложили, невозможна в SQL.

Лучше всего будет массовая вставка идентификаторов в отдельную таблицу, а затем запрос этой таблицы с использованием подвыбора или объединение идентификаторов.

например,

INSERT INTO idTable (id, context) values (@idValue, 1);
INSERT INTO idTable (id, context) values (@idValue, 1);
INSERT INTO idTable (id, context) values (@idValue, 1); // as often as you like
SELECT * FROM table1, idTable WHERE table1.id == idTable.id and idTable.context = 1

Контекст должен быть уникальным значением, которое идентифицирует диапазон Id.Это важно для запуска хранимой процедуры параллельно.Без контекстной информации параллельная работа хранимой процедуры будет смешивать значения из разных вариантов выбора.

0 голосов
/ 18 августа 2010

Если количество параметров достаточно мало (<100), вы можете использовать несколько параметров </p>

SELECT * FROM table1 WHERE IN id IN (@id1, @id2, @id3)

Если оно длиннее, ищите функцию разделения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...