Работа с массивами в SQL Server - PullRequest
3 голосов
/ 21 февраля 2011

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

Есть ли способ работать с массивом этих идентификаторов в SQL Server? Я считаю, что это должно быть что-то с разбиением массива, а затем зациклить его (в SQL). Я просто не знаю как?

SQL Server 2008

Ответы [ 4 ]

5 голосов
/ 21 февраля 2011

Есть много способов сделать это:

  • Передать в параметре varchar значения, разделенные запятыми, и разобрать их (не очень эффективно, но для небольшого объема данных, не так уж и плохо, за исключением разборщика)
  • Передайте XML и используйте встроенные функции XML (SQL Server 2005+ имеет лучшую поддержку для этого, чем более ранние версии)
  • Использовать параметры табличных значений (SQL Server 2008 +)

Поскольку вы используете SQL Server 2008, используйте параметры табличных значений.

1 голос
/ 21 февраля 2011

РЕДАКТИРОВАТЬ: Пример ниже

Как уже упоминалось @Oded, лучше всего использовать табличные параметры.

Однако, если по какой-либо причине вы не можете использовать эти(возможно, ограничения вашей структуры вызовов), вы можете использовать следующее для выполнения разделения на таблицу:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[SplitToTable]
(   
    @List varchar(max), @Delim varchar(1)
)
RETURNS TABLE 
AS
RETURN
(
    WITH csvtbl(Start, [Stop]) AS (
        SELECT      Start = convert(bigint, 1), [Stop] = 
                    charindex(@Delim COLLATE Slovenian_BIN2, @list + @Delim)
        UNION ALL
        SELECT      Start = [Stop] + 1, [Stop] = charindex(@Delim 
                    COLLATE Slovenian_BIN2, @list + @Delim, [Stop] + 1)
        FROM        csvtbl
        WHERE       ([Stop] > 0)
    )
    SELECT      substring(@list, Start, CASE WHEN [Stop] > 0 THEN [Stop] - 
                Start ELSE 0 END) AS Value
    FROM        csvtbl
    WHERE       ([Stop] > 0)
)

Вам необходимо знать о глубине рекурсии по умолчанию, равной 100. Если этого недостаточно, увеличьтедобавив следующее к вашему внешнему вызову:

OPTION (MAXRECURSION 1000)  -- or 0 for unlimited

ПРИМЕР

SELECT *
FROM   MyTable as t
WHERE  t.ID IN (
       SELECT *
       FROM   dbo.SplitToTable('1,2,12,34,101', ',')
       )

Может использоваться и в соединениях и т. д.

1 голос
/ 21 февраля 2011

Я думаю, тебе нужно что-то вроде ...

Declare @query as varchar(500)
Declare @valuesList as varchar(100)
set @valuesList = '1,2,3'
set @query = 'select * From tableName where id in ( ' + @valuesList + ')'
exec(@query)
0 голосов
/ 01 марта 2011

ОБРАТИТЬ ПРОЦЕСС

DECLARE @t TABLE
(
    ID int
)

INSERT INTO @t
VALUES (1), (3), (5), (7), (9)

SELECT  STUFF(
        (
            SELECT  ',' + CAST(t.ID AS VARCHAR(10))
            FROM    @t t
            FOR     XML PATH('')
        ), 1, 1, '') AS CSV

Предоставлено SQLAuthority .

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