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

120
9

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


Item   Цвета

 Рубашка   Красный, синий, зеленый, желтый


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


Item   Цвет
Рубашка   Красный
Рубашка   Синий
Рубашка   Зеленый

 Рубашка   Желтый


Я застрял в


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


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

спросил(а) 2021-01-19T16:27:22+03:00 9 месяцев назад
1
Решение
101

Используя 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)

ответил(а) 2021-01-19T16:27:22+03:00 9 месяцев назад
79

В статье Faking Arrays в 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 этого образца. В статье у них есть постоянная таблица перечислений.

ответил(а) 2021-01-19T16:27:22+03:00 9 месяцев назад
46

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


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

ответил(а) 2021-01-19T16:27:22+03:00 9 месяцев назад
46

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

ответил(а) 2021-01-19T16:27:22+03:00 9 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема