separate comma separated values and store in table in sql server

I am having a stored procedure which gets the comma separated value as an input. I need to separate it and needs to store it in a table as individual rows.

Let the input for SP is :

Rule_ID  ListType_ID  Values
1        2            319,400,521,8465,2013

I need to store it in a table called DistributionRule_x_ListType in the below format:

Rule_ID  ListType_ID  Value
1        2            319
1        2            400
1        2            521
1        2            8465
1        2            2013

My SP looks like below:

ALTER PROCEDURE [dbo].[spInsertDistributionRuleListType]
(@Rule_ID int,
@ListType_ID int,
@Values VARCHAR(MAX)=NULL
)
AS
BEGIN

    INSERT INTO DistributionRule_x_ListType (Rule_ID,ListType_ID,Value)
    VALUES (@Rule_ID,@ListType_ID,@Values)

END

Solution 1:

You will need to create a split function similar to this:

create FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX))       
as       
begin      
    declare @idx int       
    declare @slice varchar(8000)       

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)       
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return 
end;

Then in your stored procedure, you will call the function to split your string:

ALTER PROCEDURE [dbo].[spInsertDistributionRuleListType]
(
  @Rule_ID int,
  @ListType_ID int,
  @Values VARCHAR(MAX)=NULL
)
AS
BEGIN

    INSERT INTO DistributionRule_x_ListType (Rule_ID, ListType_ID, Value)
    SELECT @Rule_ID, @ListType_ID, items
    FROM [dbo].[Split] (@Values, ',')  -- call the split function 

END

When you execute the stored procedure, it will split the values and insert the multiple rows into your table:

exec spInsertDistributionRuleListType 1, 2, '319,400,521,8465,2013';

See SQL Fiddle with Demo. This will insert the following result:

| RULE_ID | LISTTYPE_ID | VALUE |
---------------------------------
|       1 |           1 |    10 |
|       1 |           2 |   319 |
|       1 |           2 |   400 |
|       1 |           2 |   521 |
|       1 |           2 |  8465 |
|       1 |           2 |  2013 |

Solution 2:

you can do it with charindex like

DECLARE @id VARCHAR(MAX)

SET @id = @Values          --'319,400,521,8465,2013,'

WHILE CHARINDEX(',', @id) > 0 
BEGIN

    DECLARE @tmpstr VARCHAR(50)
     SET @tmpstr = SUBSTRING(@id, 1, ( CHARINDEX(',', @id) - 1 ))

    INSERT  INTO DistributionRule_x_ListType
            ( Rule_ID ,
              ListType_ID ,
              Value
            )
    VALUES  ( @Rule_ID ,
              @ListType_ID ,
              @tmpstr)
            )
    SET @id = SUBSTRING(@id, CHARINDEX(',', @id) + 1, LEN(@id))
END

Solution 3:

You can do this without dbo.Split function.

Here is your sample data

SELECT * INTO #TEMP
FROM
(
     SELECT 1  Rule_ID, 2 ListType_ID, '319,400,521,8465,2013' [Values]
     UNION ALL
     SELECT 1  , 3 , '100,200' 
)TAB

Now execute the following query and will select all comma separated values for each Rule_ID and ListType_ID.

SELECT [Rule_ID],ListType_ID,
PARSENAME(REPLACE(Split.a.value('.', 'VARCHAR(100)'),'-','.'),1) 'Values' 
FROM  
(
     SELECT [Rule_ID],ListType_ID,
     CAST ('<M>' + REPLACE([Values], ',', '</M><M>') + '</M>' AS XML) AS Data 
     FROM #TEMP     
) AS A 
CROSS APPLY Data.nodes ('/M') AS Split(a)
  • SQL FIDDLE