Как разбить строку и сохранить в массив в T-SQL

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

Цвета товара
Рубашка красная, синяя, зеленая, желтая

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

Цвет элемента
Рубашка красная
Рубашка синяя
Рубашка зеленая
Рубашка желтая

Я застрял в том, как

1) Разделить/Разделить строку "Цвета" 2) Чтобы сохранить ее в массиве 3) Чтобы использовать ее в курсоре

так как я собираюсь использовать вложенный курсор для этой цели.


person kaibuki    schedule 24.11.2010    source источник


Ответы (5)


Используя Sql Server 2005+ и тип данных XML, вы можете посмотреть на следующее

DECLARE @Table TABLE(
        Item VARCHAR(250),
        Colors VARCHAR(250)
)

INSERT INTO @Table SELECT 'Shirt','Red,Blue,Green,Yellow'
INSERT INTO @Table SELECT 'Pants','Black,White'


;WITH Vals AS (
        SELECT  Item,
                CAST('<d>' + REPLACE(Colors, ',', '</d><d>') + '</d>' AS XML) XmlColumn
        FROM    @Table
)
SELECT  Vals.Item,
        C.value('.','varchar(max)') ColumnValue
FROM    Vals
CROSS APPLY Vals.XmlColumn.nodes('/d') AS T(C)
person Adriaan Stander    schedule 24.11.2010

Статья Имитация массивов в Transact SQL описывает НЕСКОЛЬКО способов решения этой проблемы, начиная от использования функции PARSENAME() (ограничение до 5 элементов) и заканчивая написанием функций CLR.

XML-ответ — это один из подробных методов, который можно выбрать для конкретного сценария.

Объединив некоторые советы, я решил проблему разделения строк следующим образом:

SET NOCOUNT ON;

DECLARE @p NVARCHAR(1000), @len INT;
SET @p = N'value 1,value 2,value 3,value 4,etc';
SET @p = ',' + @p + ',';
SET @len = LEN(@p);

-- Remove this table variable creation if you have a permanent enumeration table
DECLARE @nums TABLE (n int);
INSERT INTO @nums (n)
    SELECT A.n FROM 
    (SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY TableKey) as n FROM dbo.Table) A
    WHERE A.n BETWEEN 1 AND @len;

SELECT SUBSTRING(@p , n + 1, CHARINDEX( ',', @p, n + 1 ) - n - 1 ) AS "value"
    FROM @nums
    WHERE SUBSTRING( @p, n, 1 ) = ',' AND n < @len;

Обратите внимание, что, учитывая ограничение длины строки в 1000, у вас должна быть таблица с 1000 или более строками (dbo.Table в примере tsql), чтобы создать табличную переменную @nums в этом примере. На статье у них есть постоянная таблица перечисления.

person Luciano Carvalho    schedule 19.03.2013

Для тех, кто любит простоту:

    -- Here is the String Array you want to convert to a Table
declare @StringArray varchar(max)
set @StringArray = 'First item,Second item,Third item';

-- Here is the table which is going to contain the rows of each item in the String array
declare @@mytable table (EachItem varchar(50))

-- Just create a select statement appending UNION ALL to each one of the item in the array
set @StringArray = 'select ''' + replace(@StringArray, ',', ''' union all select ''') + ''''
-- Push the data into your table
insert into @@mytable exec (@StringArray)

-- You now have the data in an an array inside a table that you can join to other objects
select * from @@mytable
person Chandra Sekhar    schedule 22.04.2020

Я только что сделал что-то подобное, чтобы создать промежуточные таблицы для репликации исходных таблиц с использованием представлений INFORMATION_SCHEMA на связанном сервере. Но это модифицированная версия для создания желаемых результатов. Просто не забудьте удалить последние два символа из столбца «Цвета» при его отображении.

SELECT
    t.Item
    , (
        SELECT 
            x.Color + ', ' AS [data()]
        FROM 
            Items x
        WHERE 
            x.Item = t.Item
        FOR XML PATH(''), TYPE
    ).value('.', 'varchar(max)') AS Colors
FROM 
    Items t
GROUP BY 
    t.Item
person Joel Engstrom    schedule 09.06.2017

Начиная с SQL Server 2016, это можно было сделать с помощью функции OPENJSON и JSON_VALUE.

person Dima Fomin    schedule 25.03.2017