Крис,
Есть способ сделать это в T-SQL, и на самом деле это довольно просто. Во-первых, вам нужно создать функцию, подобную следующей ... (новый метод, использующий "Tally" cte, основанный на нуле, это противно быстро, потому что он не объединяет разделители).
CREATE FUNCTION dbo.DelimitedSplit8KNEW
--===== Created by Jeff Moden (Prototype: Testing Still in Progress)
--===== Define I/O parameters
(
@pString VARCHAR(8000),
@pDelimiter CHAR(1)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
WITH
E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), --10
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --100
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10,000
cteTally(N) AS (
SELECT 0 UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E4
)
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY t.N),
ItemValue = SUBSTRING(@pString,t.N+1,ISNULL(NULLIF(CHARINDEX(@pDelimiter,@pString,t.N+1),0),DATALENGTH(@pString)+1)-t.N-1)
FROM cteTally t
WHERE t.N BETWEEN 0 AND DATALENGTH(@pString)
AND (SUBSTRING(@pString,t.N,1) = @pDelimiter OR t.N = 0)
;
GO
Теперь, чтобы увидеть, как это используется ... допустим, у вас есть таблица с уникальным столбцом и столбец CSV следующим образом (это также строит данные). Все, что нам нужно сделать, это ПРИМЕНИТЬ КРЕСТОВУЮ исходные данные с помощью функции, и данные будут волшебным образом разделены и готовы к объединению с другой таблицей:
--===== This just builds some test data
-- and is not a part of the solution
SELECT *
INTO #TestTable
FROM (
SELECT 1,'3,4,9' UNION ALL
SELECT 2,'3,2,100' UNION ALL
SELECT 3,'14,35,8,21,27,12'
) d (RowNum,CsvValue)
;
--===== Split the data out giving the unique RowNum
-- from the original data, the element position,
-- the the value of the split element. You can
-- join this SELECT with a table to get the other
-- values.
SELECT data.RowNum, split.ItemNumber, split.ItemValue
FROM #TestTable data
CROSS APPLY dbo.DelimitedSplit8KNEW(data.CsvValue,',') split
;
Вот вывод ...
RowNum ItemNumber ItemValue
----------- -------------------- ---------
1 1 3
1 2 4
1 3 9
2 1 3
2 2 2
2 3 100
3 1 14
3 2 35
3 3 8
3 4 21
3 5 27
3 6 12
(12 row(s) affected)