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
)