My google searches on how to split a string on a delimiter have resulted in some useful functions for splitting strings when the string is known (i.e. see below):
Fix it the right way--make that column a related table. No good ever comes of comma-separated scalar columns.
You could try something like:
SELECT s.Items AS SplitValue, ValueColumn1, ValueColumn2
FROM MyTable, Split(CommaColumn,',') AS s
+1 to the anti-CSV comments, but if you must do this you would use CROSS APPLY or OUTER APPLY.
Yes, it's possible with CROSS APPLY (SQL 2005+):
with testdata (CommaColumn, ValueColumn1, ValueColumn2) as (
select 'ABC,123', 1, 2 union all
select 'XYZ, 789', 2, 3
)
select
b.items as SplitValue
, a.ValueColumn1
, a.ValueColumn2
from testdata a
cross apply dbo.Split(a.CommaColumn,',') b
Notes:
You should add an index to the result set of your split column, so that it returns two columns, IndexNumber and Value.
In-line implementations with a numbers table are generally faster than your procedural version here.
eg:
create function [dbo].[Split] (@list nvarchar(max), @delimiter nchar(1) = N',')
returns table
as
return (
select
Number = row_number() over (order by Number)
, [Value] = ltrim(rtrim(convert(nvarchar(4000),
substring(@list, Number
, charindex(@delimiter, @list+@delimiter, Number)-Number
)
)))
from dbo.Numbers
where Number <= convert(int, len(@list))
and substring(@delimiter + @list, Number, 1) = @delimiter
)
Erland Sommarskog has the definitive page on this, I think: http://www.sommarskog.se/arrays-in-sql-2005.html
alter procedure [dbo].[usp_split](@strings varchar(max)) as
begin
Declare @index int
set @index=1
declare @length int
set @length=len(@strings)
declare @str varchar(max)
declare @diff int
declare @Tags table(id varchar(30))
while(@index<@length)
begin
if(@index='1')
begin
set @str=(SELECT substring(@strings, @index, (charindex(',',(substring(@strings, @index,(@length)))))-1))
insert into @Tags values(@str)
set @index=(charindex(',',(substring(@strings, @index,(@length)))))
end
else
begin
set @diff=@length-@index
if(@diff !=0)
begin
set @str=(select substring(@strings, @index, (charindex(',',(substring(@strings,@index,@diff))))-1))
if(@str is not null and @str!='')
begin
insert into @Tags VALUES(@str)
end
set @index=@index +(charindex(',',(substring(@strings, @index,@diff))))
end
end
end
set @str=(select right(@strings,(charindex(',',(substring(reverse(@strings),1,(@length)))))-1))
insert into @Tags VALUES(@str)
select id from @Tags
end
Usage:
exec usp_split '1212,21213,1,3,133,1313131,1,231313,5'