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