Вы можете попробовать этот крошечный метод линейного разбиения.
DECLARE @s VARCHAR(MAX)='05/10/2018 21:14,#FXAAF00123456,,Cup 1 X Plane,0.00000,OK,Cup 1 Y Plane,0.00000,OK,Cup 1 Z Plane,40.64252,OK,Cup 2 X Plane,77.89434,OK';
;WITH
a AS (SELECT n=0, i=-1, j=0 UNION ALL SELECT n+1, j, CAST(CHARINDEX(',', @s, j+1) AS INT) FROM a WHERE j > i)
,b AS (SELECT n, SUBSTRING(@s, i+1, IIF(j>0, j, LEN(@s)+1)-i-1) s FROM a WHERE i >= 0)
,c AS (SELECT n,(n-1) % 3 AS Position,(n-1)/3 AS RowIndex,s FROM b)
SELECT MAX(CASE WHEN Position=0 THEN s END) AS part1
,MAX(CASE WHEN Position=1 THEN s END) AS part2
,MAX(CASE WHEN Position=2 THEN s END) AS part3
FROM c
GROUP BY RowIndex
OPTION (MAXRECURSION 0);
Результат
part1 part2 part3
05/10/2018 21:14 #FXAAF00123456
Cup 1 X Plane 0.00000 OK
Cup 1 Y Plane 0.00000 OK
Cup 1 Z Plane 40.64252 OK
Cup 2 X Plane 77.89434 OK
Подсказка
Вы можете изменить функцию разделения на рекурсивный подход, описанный выше,С одной стороны, вы ограничены длиной строки в sys.all_objects
, которая может быть меньше, чем ваш ввод.С другой стороны, ваш подход должен проверять каждую позицию, в то время как рекурсивный подход прыгает с места на место.Должно быть быстрее ...
Это можно легко открыть для многосимвольного разделителя , если необходимо ...
ОБНОВИТЬ другой подход без рекурсии
...что делает его неуклюжим для использования в функции сплиттера (из-за OPTION MAXRECURSION(0)
, который должен быть помещен в конце запроса и не может находиться внутри функции).Попробуйте:
;WITH
a(Casted) AS (SELECT CAST('<x>' + REPLACE((SELECT @s AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML))
,b(s,RowIndex,Position) AS
(
SELECT x.value(N'text()[1]','nvarchar(max)')
,(ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) -1) /3
,(ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) -1) %3
FROM a
CROSS APPLY Casted.nodes(N'/x') X(x)
)
SELECT RowIndex
,MAX(CASE WHEN Position=0 THEN s END) AS part1
,MAX(CASE WHEN Position=1 THEN s END) AS part2
,MAX(CASE WHEN Position=2 THEN s END) AS part3
FROM b
GROUP BY RowIndex;
Подсказка:
Использование (SELECT @s AS [*] FOR XML PATH(''))
позволит сохранить этот подход с запрещенными символами ...