千家信息网

几种分割字符串实现方法的比较

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,在数据库开发中,有时会遇到把字符串,按一定规则进行分割,比如"a,b,c,1,2,3"这样的以逗号为分隔符的字符串,需要把分割出来,分割后单独变行一行记录。首先想到的是使用替换函数把分隔符去掉。于是有
千家信息网最后更新 2024年11月23日几种分割字符串实现方法的比较

在数据库开发中,有时会遇到把字符串,按一定规则进行分割,比如"a,b,c,1,2,3"这样的以逗号为分隔符的字符串,需要把分割出来,分割后单独变行一行记录。首先想到的是使用替换函数把分隔符去掉。于是有了:

IF (OBJECT_ID(N'Tempdb..##T1') IS NOT NULL)BEGIN    DROP TABLE ##T1;ENDGODECLARE @string NVARCHAR(MAX);SET @string=N'123,abc,456,AAA,DDD';SET @string=N'SELECT * INTO ##T1 FROM (SELECT ''' +             REPLACE(@string,',',''' AS result UNION ALL SELECT ''') + ''') a' ;EXEC(@string);SELECT * FROM ##T1;GO

Code-1: 方法1


该方法拼接SQL语句,简单巧妙,但有不足。(1)拼接的SQL不够直观,较难编写;(2)如果分隔符是半角的英文单引号的话,需要再作处理;(3)某些 情况下,如果字符串有中文等非英文字符,会显示乱码;(4)由于拼接的SQL,如果要分割的字符串很长很长,那么拼接的SQL可能会过长,而不能被执行。 所以这种方法只能作简单的替换或开拓思维之用。



方法2(推荐):

IF OBJECT_ID(N'fn_split_rowno') IS NOT NULLBEGIN    DROP FUNCTION fn_split_rowno;ENDGOCREATE FUNCTION fn_split_rowno(    @str       NVARCHAR(MAX)   ,@split     NVARCHAR(20) = ',')RETURNS @t TABLE(row_no INT ,col NVARCHAR(500))ASBEGIN    DECLARE @i INT    SET @i = 0    WHILE (CHARINDEX(@split ,@str) <> 0)    BEGIN        INSERT @t (row_no,col)        VALUES(@i + 1,SUBSTRING(@str ,1 ,CHARINDEX(@split ,@str) -1))             SET @str = STUFF(@str ,1 ,CHARINDEX(@split ,@str) + LEN(@split) -1 ,'')        SET @i = @i + 1     END      IF (@str <> '')        INSERT @t (row_no,col)        VALUES(@i + 1 ,@str)        RETURNENDGO

Code-2: 方法2(推荐)



封装成函数,方便调用,并且不会出现方法1中的问题。

SELECT * FROM fn_split_rowno(N'123,abc,456,AAA,DDD,51CTO',',')

Code-3: 调用函数



方法3(来自网络):

DECLARE @string NVARCHAR(MAX)SET @string = N'123,abc,456,AAA,DDD,博客园'SELECT REPLACE(REVERSE((LEFT(s ,CHARINDEX(',' ,s)))) ,',' ,'') AS resultFROM   (           SELECT r,REVERSE(LEFT(@string ,r)) + ',' AS s           FROM   (                      SELECT (                                 SELECT COUNT(*)                                 FROM   sys.objects                                 WHERE  NAME <= t.name                             ) AS r                      FROM   sys.objects AS t                  ) a           WHERE  r <= LEN(@string) AND LEFT(@string + ',' ,r + 1) LIKE '%,'       ) tORDER BY r

Code-3: 方法3



方法4(来自网络):

DECLARE @string NVARCHAR(MAX) SET @string = N'123,abc,456,AAA,DDD'DECLARE @idoc INT;  DECLARE @doc XML;  SET @doc = CAST('' + REPLACE(@string ,',' ,'')             + '' AS XML)EXEC sp_xml_preparedocument @Idoc OUTPUT,@docSELECT * FROM OPENXML(@Idoc ,'/Root/item' ,2) WITH ([S] VARCHAR(10)) GO

Code-4: 方法4


后面两种方法也是过于复杂,并且也有不足。




0