2016-02-25 2 views
3

У меня есть строка «1,2,3,4,5,6», я хочу, чтобы результат в массиве как:разделенные запятой строку, используя КТР

1 
2 
3 
4 
5 

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

У меня есть запрос:

with cte1 (str1,str2) AS 
(
SELECT SUBSTRING('1,2,3,4,5,6,',1,1) X, 
SUBSTRING('1,2,3,4,5,6,',CHARINDEX(',','1,2,3,4,5,6,,') +1,LEN('1,2,3,4,5,6,')-2) Y 
UNION all 
SELECT SUBSTRING(str2,1,1) X ,SUBSTRING(str2,CHARINDEX(',',str2)+1,LEN(str2)-2) Y 
FROM CTE1 
WHERE SUBSTRING(str2,CHARINDEX(',',str2)+0,1) <> ' ') 
SELECT str1 FROM CTE1; 

, который дает результат, как и ожидалось. но если я меняюсь строку она дает случайные reults как:

with cte1 (str1,str2) AS 
(
SELECT SUBSTRING('24,78,45,56,',1,1) X, 
SUBSTRING('24,78,45,56,',CHARINDEX(',','24,78,45,56,') +1,LEN('24,78,45,56,')-2) Y 
UNION all 
SELECT SUBSTRING(str2,1,1) X ,SUBSTRING(str2,CHARINDEX(',',str2)+1,LEN(str2)-2) Y 
FROM CTE1 
WHERE SUBSTRING(str2,CHARINDEX(',',str2)+0,1) <> ' ') 
SELECT str1 FROM CTE1; 

результат:

2 
7 
4 
5 

enter image description here

+0

[Аарон Бертрана к спасению ...] (http://sqlperformance.com/2012/07/t-sql-queries/split-strings) –

+1

В идеале, не надо. Не начинайте с «строки, разделенной запятыми», поскольку на самом деле это не вещь *, разработанная * для хранения нескольких значений. Начните с параметра table-valued или переменной xml или переменной таблицы и т. Д. Что-то * спроектировано * для хранения нескольких значений. –

ответ

0

Это будет работать только тогда, когда строка похожа на '12,34,45,56....' ie string co ntains две цифра Прдча значения, разделенной

with cte1 (str1,str2) AS 
(
SELECT SUBSTRING('24,78,45,56,',1,2) X, 
     SUBSTRING('24,78,45,56,',CHARINDEX(',','24,78,45,56,') +1,LEN('24,78,45,56,')-2) Y 
UNION all 
SELECT SUBSTRING(str2,1,2) X ,SUBSTRING(str2,CHARINDEX(',',str2)+1,LEN(str2)-2) Y 
FROM CTE1 
WHERE SUBSTRING(str2,CHARINDEX(',',str2)+0,2) <> ' ') 
SELECT str1 FROM CTE1; 

Вы должны идти с общим решением, создав на пользователе определить функцию, которая принимает разделенные запятые строки и дать табличное значение для этой строки

определения функции, как этот

CREATE FUNCTION SplitItem(@ItemIDs VARCHAR(MAX)) 
RETURNS @ItemTable TABLE (Item VARCHAR(200)) 
AS 
BEGIN 
    DECLARE @Item VARCHAR(200) 
    DECLARE @Index INT 

    WHILE LEN(@ItemIDs) <> 0 
     BEGIN 
      SET @Index = PATINDEX('%,%', @ItemIDs) 
      IF @Index > 0 
       BEGIN 
        SET @Item = SUBSTRING(@ItemIDs, 1, @Index - 1) 
        SET @ItemIDs = RIGHT(@ItemIDs, LEN(@ItemIDs) - @Index) 
        INSERT INTO @ItemTable 
        VALUES (@Item) 
       END 
      ELSE 
       BEGIN 
        BREAK 
       END 
     END 
    SET @Item = @ItemIDs 
    INSERT INTO @ItemTable 
    VALUES (@Item) 

    RETURN 
END 

и использовать эту функцию, как это

SELECT Item 
FROM SplitItem('1,2,3,44,55,66,77') 

Это будет дает выход как этот

1 2 3 44 55 66 77

0

Вы можете использовать рекурсивное ОТВ

Declare @list NVARCHAR(MAX) = '1,2,3,4,5' 
DECLARE @length INT = LEN(@list) + 1; 

    WITH a AS 
    (
     SELECT 
      [start] = 1, 
      [end] = COALESCE(NULLIF(CHARINDEX(',', 
         @List, 1), 0), @length), 
      [value] = SUBSTRING(@list, 1, 
        COALESCE(NULLIF(CHARINDEX(',', 
         @List, 1), 0), @length) - 1) 
     UNION ALL 
     SELECT 
      [start] = CONVERT(INT, [end]) + 1, 
      [end] = COALESCE(NULLIF(CHARINDEX(',', 
         @list, [end] + 1), 0), @length), 
      [value] = SUBSTRING(@list, [end] + 1, 
        COALESCE(NULLIF(CHARINDEX(',', 
         @list, [end] + 1), 0), @length)-[end]-1) 
     FROM a 
     WHERE [end] < @length 
    ) 
    SELECT [value] 
    FROM a 
    WHERE LEN([value]) > 0 
    OPTION (MAXRECURSION 0); 
0

Вы можете сделать что-то вроде этого:

DECLARE @string NVARCHAR(MAX) = '1,2,3,4,5,6,', 
     @xml xml 

select @xml = cast('<d><q>'+REPLACE(@string,',','</q><q>')+'</q></d>' as xml) 

SELECT n.v.value('.','nvarchar(2)') 
FROM @xml.nodes('/d/q') AS n(v); 

Результат:

---- 
1 
2 
3 
4 
5 
6 


(7 row(s) affected) 
Смежные вопросы