原文:[SQL]Split函数的SQL版本。用于将字符串拆分成单列表
该函数与 .Split 函数的 .net 版本类似,只不过 .net 返回一个数组。 这将返回一个单列表,每个分割子字符串占据一行。 可选是否删除空子字符串和重复项。 市面上类似的函数并不多,但大多数都是在循环中改变原来的字符串。 我觉得这样不好。 虽然我不知道SQL字符串是否像.net字符串一样不可变,但我觉得我应该尽量不这样做。 最好移动原来的弦。 如果 SQL 字符串不可变,则每次更改时都会生成一个副本。 尤其是循环每次都变化的时候,内存消耗让人心疼,于是就有了重新发明轮子的想法。 。
另外,如果SQL开启了CLR支持,则可以封装一个.net Split并在SQL中使用。 这是最简单的,性能应该会更好(猜测)。 废话不多说,函数如下:
/*------------------------------- 函数:拆分字符串到单列表格v0.02 Author:AhDung Update:201403251158 -------------------------------*/ ALTER FUNCTION dbo.Split( @s VARCHAR(8000), --要拆分的字符串 @separator NVARCHAR(10), --分隔符。最长支持10个字符的分隔符 @removeEmpty BIT, --是否移除空格项目。不处理制表符、回车换行 @unique BIT --是否移除重复项 ) RETURNS @t TABLE (S VARCHAR(500)) AS BEGIN IF @s IS NULL RETURN IF CHARINDEX(@separator,@s)=0 BEGIN INSERT @t VALUES(LEFT(@s,250)) RETURN END SET @s += @separator --仅对原串做一次改动。其实一次不改也行,但需要在循环中加判断。这样是为了在CPU和内存消耗之间取平衡 DECLARE @lenS INT = LEN(@s),@lenSptr INT = DATALENGTH(@separator)/2,@i INT=0,@tmp NVARCHAR(250),@nextSptrIndex INT WHILE @i < @lenS BEGIN SET @nextSptrIndex=CHARINDEX(@separator,@s,@i+1) SET @tmp=SUBSTRING(@s,@i+1,@nextSptrIndex-1-@i) INSERT INTO @t VALUES(@tmp) SET @i+=DATALENGTH(@tmp)/2+@lenSptr END IF @removeEmpty=1 BEGIN DELETE @t WHERE S='' END IF @unique=1 BEGIN WITH cteA AS (SELECT ROW_NUMBER() OVER(PARTITION BY S ORDER BY S) AS 'ID' FROM @t) DELETE cteA WHERE ID<>1 END RETURN END
写完了!