• Thanks David.  If you're on SQL 2005 it's a simple matter of converting the function to a CTE and adding a ROW_NUMBER() to it.  I set it up that way initially but noticed some performance was lost.  For SQL 2000 it's more complicated, and your best bet might be to change the UDF to a regular table-valued function and INSERT the results into a table variable with an IDENTITY column.  Again,  you'll lose performance that way, but depending on your situation it might be worth it.

    Below is an example on SQL 2005 using a CTE and the ROW_NUMBER() function.  Note that I don't have a SQL 2005 installation handy, so I wasn't able to test this before posting.  There may be a syntax error or two in it, but you get the idea.

    CREATE FUNCTION dbo.fnSetSplit (@String VARCHAR(8000))

    RETURNS TABLE

    AS

    RETURN (

        WITH Splitter(Num, String) AS

        (

        SELECT Num,

            SUBSTRING(@String,

                CASE Num

                    WHEN 1 THEN 1

                    ELSE Num + 1

                END,

                CASE CHARINDEX(',', @String, Num + 1)

                    WHEN 0 THEN LEN(@String) - Num + 1

                    ELSE CHARINDEX(',', @String, Num + 1) - Num -

                        CASE

                            WHEN Num > 1 THEN 1

                            ELSE 0

                        END

                   END

                ) AS String

        FROM dbo.Numbers

        WHERE Num <= LEN(@String)

            AND (SUBSTRING(@String, Num, 1) = ','

                OR Num = 1)

        )

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

        FROM Splitter

    )