You should try and avoid cursors where possible, they are a basic loop that leads to Row-by-Row solutions that can be very slow on large SQL datasets. Cursors also reserve space in the Buffer (memory) and can steal resources from other processes. If you have to loop you should use a WHILE construct.
SQL offers other SET based solutions that can replace a CURSOR solution.
Your goal may more efficiently be achieved with a Recursive CTE.
Here's an example of a Recursive CTE that can replace the need for your cursor:
CREATE TABLE #Splitter
(
Id INT
,Vals VARCHAR(10)
)
INSERT INTO #Splitter VALUES
(1,'A,B,C'),
(2,'D,E,F')
;WITH cte AS
(
--Anchor point, the first Value from each ID
SELECT
Id
,LEFT(Vals,CHARINDEX(',',Vals)-1) AS Val
,RIGHT(Vals,LEN(Vals)-CHARINDEX(',',Vals)) AS Remainder
FROM #Splitter
WHERE
Vals IS NOT NULL AND CHARINDEX(',',Vals)>0
UNION ALL
--Central Recursion for each value
SELECT
Id,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
FROM cte
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
UNION ALL
--Error prevention, handling the end of the string
SELECT
Id,Remainder,null
FROM cte
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT ID,VAL FROM cte
If your [Vals] column is always in a set format then you could use CROSS APPLY with VALUES for a more efficient solution.
SELECT
ID
,v.Val
FROM
#Splitter S
CROSS APPLY (VALUES (left(S.Vals,1)),(SUBSTRING(Vals,3,1)),(RIGHT(Vals,1))) v(Val)
1-A
1-A
1-A
a typo? – Andrew MortonSTRING_SPLIT
anyway. – Panagiotis Kanavos1-A
s; did you instead want1-A
,1-B
,1-C
? – JohnLBevan