<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www2.sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Adam Machanic : splitting strings</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/splitting+strings/default.aspx</link><description>Tags: splitting strings</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Splitting a string of unlimited length</title><link>http://www2.sqlblog.com/blogs/adam_machanic/archive/2006/07/12/splitting-a-string-of-unlimited-length.aspx</link><pubDate>Thu, 13 Jul 2006 01:20:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:81</guid><dc:creator>Adam Machanic</dc:creator><slash:comments>14</slash:comments><comments>http://www2.sqlblog.com/blogs/adam_machanic/comments/81.aspx</comments><wfw:commentRss>http://www2.sqlblog.com/blogs/adam_machanic/commentrss.aspx?PostID=81</wfw:commentRss><description>&lt;p&gt;There are many techniques for splitting a string in T-SQL (in other
words, taking a character-delimited string and producing a table of the
values), the best of which are encapsulated in Erland Sommarskog's &lt;a href="http://www.sommarskog.se/arrays-in-sql.html" target="#"&gt;famous article&lt;/a&gt;.  My favorite of his string splitting techniques is adapted from a previous example that was created by &lt;a href="http://www.bizdatasolutions.com/tsql/sqlarrays.asp" target="#"&gt;Anith Sen&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Both of these resources are excellent, but sometimes you just need a
little bit more. None of their solutions will split a string larger
than 8000 characters in length. So I've produced my own modified
version. If you're splitting smaller strings then &lt;i&gt;by all means, use theirs!&lt;/i&gt;
This is certainly slower, but I do believe it's the fastest way in SQL
Server 2000 to split a very long string. You will require a &lt;a href="http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/you-require-a-numbers-table.aspx"&gt;numbers table&lt;/a&gt;, so make sure you have it on hand...
&lt;/p&gt;&lt;p&gt;
Anyway, the code:
&lt;/p&gt;&lt;pre class="code"&gt;CREATE FUNCTION dbo.SplitString&lt;br&gt;(&lt;br&gt;	@List TEXT,&lt;br&gt;	@Delimiter CHAR(1)&lt;br&gt;)&lt;br&gt;RETURNS @ReturnTbl TABLE &lt;br&gt;(&lt;br&gt;	OutParam VARCHAR(20)&lt;br&gt;)&lt;br&gt;WITH SCHEMABINDING&lt;br&gt;AS&lt;br&gt;BEGIN&lt;br&gt;	DECLARE @LeftSplit VARCHAR(7998)&lt;br&gt;	DECLARE @SplitStart INT SET @SplitStart = 0&lt;br&gt;	DECLARE @SplitEnd INT&lt;br&gt;	SET @SplitEnd = 7997&lt;br&gt;&lt;br&gt;	SELECT &lt;br&gt;		@SplitEnd = MAX(Number)&lt;br&gt;	FROM dbo.Numbers&lt;br&gt;	WHERE &lt;br&gt;		(&lt;br&gt;			REPLACE(SUBSTRING(@List, Number, 1), ' ', CHAR(255)) = &lt;br&gt;				REPLACE(@Delimiter, ' ', CHAR(255))&lt;br&gt;			OR Number = DATALENGTH(@List) + 1&lt;br&gt;		)&lt;br&gt;		AND Number BETWEEN @SplitStart AND @SplitEnd&lt;br&gt;&lt;br&gt;	WHILE @SplitStart &amp;lt; @SplitEnd&lt;br&gt;	BEGIN&lt;br&gt;		SET @LeftSplit = &lt;br&gt;			@Delimiter + &lt;br&gt;			SUBSTRING(@List, @SplitStart, @SplitEnd - @SplitStart) + &lt;br&gt;			@Delimiter&lt;br&gt;&lt;br&gt;		INSERT @ReturnTbl &lt;br&gt;		(&lt;br&gt;			OutParam&lt;br&gt;		)&lt;br&gt;		SELECT &lt;br&gt;			LTRIM&lt;br&gt;			(&lt;br&gt;				RTRIM&lt;br&gt;				(&lt;br&gt;					SUBSTRING&lt;br&gt;					(&lt;br&gt;						@LeftSplit, &lt;br&gt;						Number + 1,&lt;br&gt;	                    CHARINDEX(@Delimiter, @LeftSplit, Number + 1) - Number - 1&lt;br&gt;					)&lt;br&gt;				)&lt;br&gt;			) AS Value&lt;br&gt;		FROM dbo.Numbers&lt;br&gt;		WHERE  &lt;br&gt;			Number &amp;lt;= LEN(@LeftSplit) - 1&lt;br&gt;			AND REPLACE(SUBSTRING(@LeftSplit, Number, 1), ' ', CHAR(255)) = &lt;br&gt;				REPLACE(@Delimiter, ' ', CHAR(255))&lt;br&gt;			AND '' &amp;lt;&amp;gt;&lt;br&gt;				SUBSTRING&lt;br&gt;				(&lt;br&gt;					@LeftSplit, &lt;br&gt;					Number + 1, &lt;br&gt;					CHARINDEX(@Delimiter, @LeftSplit, Number + 1) - Number - 1&lt;br&gt;				)&lt;br&gt;&lt;br&gt;		SET @SplitStart = @SplitEnd + 1&lt;br&gt;		SET @SplitEnd = @SplitEnd + 7997&lt;br&gt;&lt;br&gt;		SELECT &lt;br&gt;			@SplitEnd = MAX(Number) + @SplitStart&lt;br&gt;		FROM dbo.Numbers&lt;br&gt;		WHERE &lt;br&gt;			(&lt;br&gt;				REPLACE(SUBSTRING(@List, Number + @SplitStart, 1), ' ', CHAR(255)) = &lt;br&gt;					REPLACE(@Delimiter, ' ', CHAR(255))&lt;br&gt;				OR Number + @SplitStart = DATALENGTH(@List) + 1&lt;br&gt;			)&lt;br&gt;			AND Number BETWEEN 1 AND @SplitEnd - @SplitStart&lt;br&gt;	END&lt;br&gt;&lt;br&gt;	RETURN&lt;br&gt;END&lt;br&gt;GO&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;
This code does nothing more than chunk up the string, using the
delimiter as boundries, into small enough pieces (&amp;lt; 8000 characters)
that CHARINDEX can be used on them. Then the same algorithm from
Erland's split string is applied.
&lt;/p&gt;&lt;p&gt;Note that this function does not gracefully handle situations
such as passing in the wrong delimiter. So please carefully test your
code before deploying this!
&lt;/p&gt;&lt;p&gt;
Using the function is quite simple:
&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre class="code"&gt;SELECT * &lt;br&gt;FROM dbo.SplitString('something, something else, etc, etc, etc...', ',')&lt;br&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;hr&gt;
&lt;p&gt;Update, February 15, 2005: Fixed so that only 8000 numbers are
needed in the Numbers table for this to work. Previously required as
many numbers as were present in the string to be split.&lt;/p&gt;&lt;p&gt;Update, February 23, 2009: Four years since the last update and a new bug is discovered by the insightful Craig Hathaway! Fixed the function so that it now handles space as a delimiter. Thanks, Craig!&lt;br&gt;&lt;/p&gt;&lt;br&gt;&lt;img src="http://www2.sqlblog.com/aggbug.aspx?PostID=81" width="1" height="1"&gt;</description><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/Scripts/default.aspx">Scripts</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/splitting+strings/default.aspx">splitting strings</category><category domain="http://www2.sqlblog.com/blogs/adam_machanic/archive/tags/T-SQL/default.aspx">T-SQL</category></item></channel></rss>