0
  1. Working on SQL (2005 and 2008)

  2. the variable with value '1,2,3' would be call @cedis and this could to have N number for example

    set @cedis='1' or set @cedis='1,2,3,4,5,6,7' or set @cedis='125,98,91'
    
  3. so important, its this must to be a select only, a loop could not to be use, only a select!

  4. this must to return a (result as ) table with values for example

    set @cedis='1,2,3,4' this must to return a result 
    number 1 2 3 4
    
    declare @cedis varchar(max)
    set @cedis='1,58,123,8'
    ;with datos as 
    (
       my select with is going to return me the table
    )
    select * from datos 
    

result set is

number
1
58
123
8
angel
  • 4,474
  • 12
  • 57
  • 89
  • The doesn't make any sense. Please rephrase your question if you want a chance of someone being able to help you. – Rubix Rechvin Jan 15 '15 at 17:19
  • So, you want a query that returns a set of numbers? What for? – DaaaahWhoosh Jan 15 '15 at 17:20
  • SQL Server doesn't support arrays... – Christian Wattengård Jan 15 '15 at 17:21
  • yes, you set '1,2,3' and this must to return a table i could do it but with loops – angel Jan 15 '15 at 17:21
  • 1
    http://stackoverflow.com/questions/697519/split-function-equivalent-in-t-sql – Christian Wattengård Jan 15 '15 at 17:22
  • Angel, no you should not do it will loops. Yes, this is a duplicate of the question linked by @ChristianWattengård (and about 500 others since nobody ever thinks to search on "split" before asking how to do it). Just FYI, if you want a fast, free way to do it, the [SQL#](http://www.SQLsharp.com/) SQLCLR library (which I wrote, but the split functions, and others, are free) has `String_Split` and `String_Split4k` (for when the input is always <= 4000 chars). – Solomon Rutzky Jan 15 '15 at 17:38

4 Answers4

1

If am not wrong this is what you need

DECLARE @cedis VARCHAR(500)='1,2,3,4'

SELECT Split.a.value('.', 'VARCHAR(100)') Numbers
FROM   (SELECT Cast ('<M>' + Replace(@cedis, ',', '</M><M>') + '</M>' AS XML) AS Numbers) AS A
       CROSS APPLY Numbers.nodes ('/M') AS Split(a) 

Result:

Numbers
-------
1
2
3
4
Pரதீப்
  • 91,748
  • 19
  • 131
  • 172
  • @angel It's an ok answer, certainly _much_ better than any while loop. But it will break if you split a string containing either `<` or `&`. Just FYI. – Solomon Rutzky Jan 15 '15 at 17:42
0

A table valued function would do it.

CREATE FUNCTION [dbo].[fn_Split](@text VARCHAR(MAX), @delimiter VARCHAR(5) = ',')
RETURNS @Strings TABLE
(    
    position int IDENTITY PRIMARY KEY,
    value VARCHAR(8000)  
)
AS
BEGIN
    DECLARE @index int 
    SET @index = -1 
    WHILE (LEN(@text) > 0) 
        BEGIN  
            SET @index = CHARINDEX(@delimiter , @text)  
            IF (@index = 0) AND (LEN(@text) > 0)  
                BEGIN   
                    INSERT INTO @Strings VALUES (@text)
                    BREAK  
                END  
            IF (@index > 1)
                BEGIN
                    INSERT INTO @Strings VALUES (LEFT(@text, @index - 1))
                END
            SET @text = RIGHT(@text, (LEN(@text) - (@index+LEN(@delimiter)-1))) 
        END
    RETURN
END

You can call it as follows:

SELECT *
FROM dbo.fn_Split(@cedis,',')
Dharmendar Kumar 'DK'
  • 2,082
  • 17
  • 18
  • Please do not use (or post) WHILE-based string splitters. They are probably the slowest method. Look into using a SQLCLR, Inline Tally-table, or XML -based splitter instead. – Solomon Rutzky Jan 15 '15 at 17:35
0

Here is a more generic solution that breaks any given string into a table based on any given separator:

http://rextester.com/VSRDLS48817

Not an original idea, but I've found it very useful.

create function [dbo].[SplitString] 
(
    @str nvarchar(255), 
    @separator char(1)
)
returns table
AS
return (
with tokens(p, a, b) AS (
    select 
        cast(1 as int), 
        cast(1 as int), 
        charindex(@separator, @str)
    union all
    select
        p + 1, 
        b + 1, 
        charindex(@separator, @str, b + 1)
    from tokens
    where b > 0
)
select
    p-1 ItemIndex,
    substring(
        @str, 
        a, 
        case when b > 0 then b-a ELSE LEN(@str) end) 
    AS Item
from tokens
);
Pரதீப்
  • 91,748
  • 19
  • 131
  • 172
Ben
  • 485
  • 9
  • 19
0

This is another one approach to get required output result

DECLARE @cedis VARCHAR(MAX) ,
@delimeter VARCHAR(10)

SET @cedis = '1,58,123,8,14144,15,155231,15,3647,2347,45,76,68,2354,577,5'
SET @delimeter = ','
SET @cedis = @cedis + @delimeter;
WITH    datos
          AS ( SELECT   n = 1
               UNION ALL
               SELECT   n + 1
               FROM     datos
               WHERE    n <= LEN(@cedis)
             ),
        cte
          AS ( SELECT   T.N ,
                        ROW_NUMBER() OVER ( ORDER BY T.N ) AS RN
               FROM     datos AS T
               WHERE    SUBSTRING(@cedis, T.N, LEN(@delimeter)) = @delimeter
                        AND LEN(@cedis) >= T.N
             )
    SELECT  SUBSTRING(@cedis, COALESCE(R.N + LEN(@delimeter), 1),
                      L.N - COALESCE(R.N + LEN(@delimeter), 1)) AS part ,
            L.RN AS ID
    FROM    cte AS L
            LEFT JOIN cte AS R ON L.RN = R.RN + 1
OPTION  ( MAXRECURSION 1000 )
Vasily
  • 5,707
  • 3
  • 19
  • 34