• Hi Simon,

    Thanks for the catch.  I don't know why I didn't test it with data with an empty first element in the list! (Doh!) Here's your solution converted over to take advantage of the SQL 2005 ROW_NUMBER() function and CTEs:

    CREATE

    FUNCTION dbo.fnSetSplitSV (@String VARCHAR(MAX),

        @Delim VARCHAR(5))

    RETURNS TABLE

    AS

    RETURN

    (

        WITH Splitter (Num, String)

        AS

        (

            SELECT Num, SUBSTRING(@String,

                CASE Num + DATALENGTH(@Delim)

                    WHEN DATALENGTH(@Delim) THEN DATALENGTH(@Delim)

                    ELSE Num + DATALENGTH(@Delim)

                END - DATALENGTH(@Delim),

                CASE CHARINDEX(@Delim, @String, Num)

                    WHEN 0 THEN LEN(@String) - Num + DATALENGTH(@Delim)

                    ELSE CHARINDEX(@Delim, @String, Num) - Num

                END

            ) AS String

            FROM dbo.Numbers

            WHERE Num <= LEN(@String)

                AND (SUBSTRING(@String, Num - DATALENGTH(@Delim),

                    DATALENGTH(@Delim)) LIKE @Delim

                OR Num = 0)

        )

        SELECT ROW_NUMBER() OVER (ORDER BY Num) AS Row, Num, String

        FROM Splitter

    )