3

How can I get values from a comma separated string in SQL Server in to rows, in order to insert them into a table?

For example, with this data:

 Declare @string as nvarchar(max);
 Declare @substring as nvarchar(50);
 set @string = "Apple, Banana, Cherry, Orange, Mango"

I have currently hard-coded set @last = 2, for this example but @last should contain the number of words in the string. The parameter @substring will contain each fruit one by one in the loop, which I want to use to insert into a target table.

Here's my current code, but I'm stuck with how to set @last to the required value:

DECLARE @first AS INT
SET @first = 1
DECLARE @step AS INT
SET @step = 1
DECLARE @last AS INT
SET @last = 2

BEGIN TRANSACTION
WHILE(@first <= @last)
BEGIN

INSERT INTO tbFruit(Name)   
VALUES(@substring);

SET @first += @step
END
COMMIT TRANSACTION
Tanner
  • 22,205
  • 9
  • 65
  • 83

2 Answers2

4

You can do it all in one go rather than use a WHILE loop. So in this code, it will push the values into rows of a temp table, before using it to INSERT into a target table:

Sample code for splitting comma separated values to rows taken from:

Convert Comma Separated column value to rows

DECLARE @string AS NVARCHAR(MAX);
DECLARE @substring AS NVARCHAR(50);
SET @string = 'Apple, Banana, Cherry, Orange, Mango'

SELECT Split.a.value('.', 'VARCHAR(100)') AS Fruits
INTO   #fruits
FROM   
   (
     SELECT CAST ('<M>' + REPLACE(@string, ', ', '</M><M>') + '</M>' AS XML) AS String
   ) AS A
     CROSS APPLY String.nodes('/M') AS Split ( a ); 

-- show what's in the temp table
SELECT *
FROM   #fruits

At this point you have the values in rows in a temp table, which you can use to populate your target table like so:

INSERT INTO tbFruit ( Name )
SELECT Fruits FROM #fruits

-- show what's in the target table
SELECT * FROM   #target_table

-- tidy up
DROP TABLE #fruits

SQL Fiddle Demo

TSQL Code:

 DECLARE @string AS NVARCHAR(MAX) = 'Apple, Banana, Cherry, Orange, Mango'
 DECLARE @substring AS NVARCHAR(50)

 SELECT Split.a.value('.', 'VARCHAR(100)') AS Fruits
 INTO   #fruits
 FROM   ( SELECT    CAST ('<M>' + REPLACE(@string, ', ', '</M><M>') + '</M>' AS XML) AS String
        ) AS A
        CROSS APPLY String.nodes('/M') AS Split ( a )   

 CREATE TABLE #target_table ( Fruits NVARCHAR(50) )

 INSERT INTO #target_table
        ( fruits )
        SELECT  *
        FROM    #fruits

 SELECT * FROM   #target_table

 DROP TABLE #fruits
 DROP TABLE #target_table

Results:

| FRUITS |
|--------|
|  Apple |
| Banana |
| Cherry |
| Orange |
|  Mango |
Community
  • 1
  • 1
Tanner
  • 22,205
  • 9
  • 65
  • 83
0

Try the below code:

DECLARE @string VARCHAR(MAX),
@Split CHAR(1),
@X xml

--The String containg the fruit names separated by comma.
SELECT @string = 'Apple, Banana, Cherry, Orange, Mango',

--Separator in the String.
@Split = ','

--Use XML to extract the fruit names.
SELECT @X = CONVERT(xml,'<root><s>' + REPLACE(@string,@Split,'</s><s>') + '</s></root>')

--Insert the fruit names into the table.
INSERT INTO tbFruit (Name) SELECT T.c.value('.','varchar(max)')
FROM @X.nodes('/root/s') T(c)
Veera
  • 3,412
  • 2
  • 14
  • 27