sql 使用T-SQL将一串comman分隔的int分成Ints表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sql 使用T-SQL将一串comman分隔的int分成Ints表相关的知识,希望对你有一定的参考价值。


--Recently, I came across a piece of TSQL code that would take a comma separated string as an input 
--and parse it to return a single column table from it. 

--Lets' call this function as Split1. The code is as follows:

 

CREATE FUNCTION [dbo].Split1(@input AS Varchar(4000) )
RETURNS
      @Result TABLE(Value BIGINT)
AS
BEGIN
      DECLARE @str VARCHAR(20)
      DECLARE @ind Int
      IF(@input is not null)
      BEGIN
            SET @ind = CharIndex(',',@input)
            WHILE @ind > 0
            BEGIN
                  SET @str = SUBSTRING(@input,1,@ind�1)
                  SET @input = SUBSTRING(@input,@ind+1,LEN(@input)-@ind)
                  INSERT INTO @Result values (@str)
                  SET @ind = CharIndex(',',@input)
            END
            SET @str = @input
            INSERT INTO @Result values (@str)
      END
      RETURN
END


--This is a very old fashioned (but still effective enough) script which does a loop over a string to cut out all possible 
-- string values that are separated by a comma.

GO

--Let's see now, how the same could be achieved in modern day TSQL languages (such as SQL 2005 and above).
--Approach 1:  Common Table Expression (CTE)
--Lets call this function as Split2.  here we are using

CREATE FUNCTION dbo.Split2 ( @strString varchar(4000))
RETURNS  @Result TABLE(Value BIGINT)
AS
begin
    WITH StrCTE(start, stop) AS
    (
      SELECT  1, CHARINDEX(',' , @strString )
      UNION ALL
      SELECT  stop + 1, CHARINDEX(',' ,@strString  , stop + 1)
      FROM StrCTE
      WHERE stop > 0
    )
   
    insert into @Result
    SELECT   SUBSTRING(@strString , start, CASE WHEN stop > 0 THEN stop�start ELSE 4000 END) AS stringValue
    FROM StrCTE
   
    return
end   
 

GO

 

--Approach 2:  XML (surprise)
--XML could be applied to do some type of string parsing (see this) Let's call this function as Split3.


CREATE FUNCTION dbo.Split3 ( @strString varchar(4000))

RETURNS  @Result TABLE(Value BIGINT)
AS
BEGIN
 
      DECLARE @x XML 
      SELECT @x = CAST('<A>'+ REPLACE(@strString,',','</A><A>')+ '</A>' AS XML)
     
      INSERT INTO @Result            
      SELECT t.value('.', 'int') AS inVal
      FROM @x.nodes('/A') AS x(t)
 

    RETURN
END   
GO
 

--Approach 4: Classic TSQL Way
--I got this approach from SQL Server Central site. This approach is slightly unusual 
-- but very effective. this needs you to create a table of sequential numbers called a Tally Table.

 

SELECT TOP 11000 -- equates to more than 30 years of dates       
IDENTITY(INT,1,1) AS N  
INTO dbo.Tally  
FROM Master.dbo.SysColumns sc1,       
Master.dbo.SysColumns sc2

--Lets index the table for better performance.

ALTER TABLE dbo.Tally   
ADD CONSTRAINT PK_Tally_N PRIMARY KEY CLUSTERED (N)
WITH FILLFACTOR = 100
 

--Finally out Split4 function.

GO

CREATE FUNCTION dbo.Split4 ( @strString varchar(4000))
RETURNS  @Result TABLE(Value BIGINT)
AS
BEGIN
 
      SET @strString = ','+@strString +','
     
      INSERT INTO @t  (Value)
      SELECT SUBSTRING(@strString,N+1,CHARINDEX(',',@strString,N+1)-N�1)  
      FROM dbo.Tally 
      WHERE N < LEN(@strString)   
      AND SUBSTRING(@strString,N,1) = ',' �Notice how we find the comma
 

      RETURN
END   
GO
 

--Now, what about the most crucial question: Performance.  so lets put all 4 functions to test.
DECLARE @str VARCHAR(4000) = '6,7,7,8,10,12,13,14,16,44,46,47,394,396,417,488,714,717,718,719,722,725,811,818,832,833,836,837,846,913,914,919,922,923,924,925,926,927,927,928,929,929,930,931,932,934,935,1029,1072,1187,1188,1192,1196,1197,1199,1199,1199,1199,1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1366,1367,1387,1388,1666,1759,1870,2042,2045,2163,2261,2374,2445,2550,2676,2879,2880,2881,2892,2893,2894'
SELECT * FROM dbo.split1 ( @str )  
SELECT * FROM dbo.split2 ( @str )  
SELECT * FROM dbo.split3 ( @str )  
SELECT * FROM dbo.split3 ( @str )  

以上是关于sql 使用T-SQL将一串comman分隔的int分成Ints表的主要内容,如果未能解决你的问题,请参考以下文章

将一串空格分隔的单词拆分为多行[重复]

使用 T-SQL,从字符串中返回第 n 个分隔元素

在 T-SQl 中使用 like 搜索由未知数量的空格分隔的单词

T-SQL -- 将逗号分隔的列转换为多列

T-SQL拆分使用指定分隔符的字符串(split string)

PL SQL从用逗号分隔的字符串创建数字数组[重复]