-- The simple fixed-length function, which is waterproof when using fn_nums -
-- at least it will never miss an element. Query plan on the other hand...
CREATE FUNCTION fn_fixstring_single(@str nvarchar(MAX), @itemlen tinyint)
RETURNS TABLE
RETURN(SELECT listpos = n.Number,
str = rtrim(convert(nvarchar(4000),
substring(@str, @itemlen * (n.Number - 1) + 1, @itemlen)))
FROM fn_nums(len(@str) / @itemlen +
CASE len(@str) % @itemlen WHEN 0 THEN 0 ELSE 1 END) AS n)
go
-- A special version for integers that works on a binary string.
CREATE FUNCTION fn_fixbinary_single(@str varbinary(MAX))
RETURNS TABLE
AS
RETURN(SELECT listpos = n.Number,
n = convert(int, substring(@str, 4 * (n.Number - 1) + 1, 4))
FROM fn_nums(datalength(@str) / 4 ) AS n)
go
-- The same as fixstring_single, but as a multi-statement function.
CREATE FUNCTION fn_fixstring_mstmt(@str nvarchar(MAX), @itemlen tinyint)
RETURNS @t TABLE (listpos int NOT NULL,
str nvarchar(4000) NOT NULL) AS
BEGIN
INSERT @t (listpos, str)
SELECT listpos = n.Number,
str = rtrim(
substring(@str, @itemlen * (n.Number - 1) + 1, @itemlen))
FROM fn_nums(len(@str) / @itemlen +
CASE len(@str) % @itemlen WHEN 0 THEN 0 ELSE 1 END) n
RETURN
END