Split function equivalent in T-SQL?

后端 未结 15 1848
深忆病人
深忆病人 2020-11-21 07:23

I’m looking to split \'1,2,3,4,5,6,7,8,9,10,11,12,13,14,15...\' (comma delimited) into a table or table variable.

Does anyone have a function that returns each one

相关标签:
15条回答
  • 2020-11-21 07:48
    CREATE FUNCTION Split
    (
      @delimited nvarchar(max),
      @delimiter nvarchar(100)
    ) RETURNS @t TABLE
    (
    -- Id column can be commented out, not required for sql splitting string
      id int identity(1,1), -- I use this column for numbering splitted parts
      val nvarchar(max)
    )
    AS
    BEGIN
      declare @xml xml
      set @xml = N'<root><r>' + replace(@delimited,@delimiter,'</r><r>') + '</r></root>'
    
      insert into @t(val)
      select
        r.value('.','varchar(max)') as item
      from @xml.nodes('//root/r') as records(r)
    
      RETURN
    END
    GO
    

    usage

    Select * from dbo.Split(N'1,2,3,4,6',',')
    
    0 讨论(0)
  • 2020-11-21 07:54

    Here is somewhat old-fashioned solution:

    /*
        Splits string into parts delimitered with specified character.
    */
    CREATE FUNCTION [dbo].[SDF_SplitString]
    (
        @sString nvarchar(2048),
        @cDelimiter nchar(1)
    )
    RETURNS @tParts TABLE ( part nvarchar(2048) )
    AS
    BEGIN
        if @sString is null return
        declare @iStart int,
                @iPos int
        if substring( @sString, 1, 1 ) = @cDelimiter 
        begin
            set @iStart = 2
            insert into @tParts
            values( null )
        end
        else 
            set @iStart = 1
        while 1=1
        begin
            set @iPos = charindex( @cDelimiter, @sString, @iStart )
            if @iPos = 0
                set @iPos = len( @sString )+1
            if @iPos - @iStart > 0          
                insert into @tParts
                values  ( substring( @sString, @iStart, @iPos-@iStart ))
            else
                insert into @tParts
                values( null )
            set @iStart = @iPos+1
            if @iStart > len( @sString ) 
                break
        end
        RETURN
    
    END
    

    In SQL Server 2008 you can achieve the same with .NET code. Maybe it would work faster, but definitely this approach is easier to manage.

    0 讨论(0)
  • 2020-11-21 07:55

    This blog came with a pretty good solution using XML in T-SQL.

    This is the function I came up with based on that blog (change function name and result type cast per need):

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE FUNCTION [dbo].[SplitIntoBigints]
    (@List varchar(MAX), @Splitter char)
    RETURNS TABLE 
    AS
    RETURN 
    (
        WITH SplittedXML AS(
            SELECT CAST('<v>' + REPLACE(@List, @Splitter, '</v><v>') + '</v>' AS XML) AS Splitted
        )
        SELECT x.v.value('.', 'bigint') AS Value
        FROM SplittedXML
        CROSS APPLY Splitted.nodes('//v') x(v)
    )
    GO
    
    0 讨论(0)
  • 2020-11-21 07:57

    Try this

    DECLARE @xml xml, @str varchar(100), @delimiter varchar(10)
    SET @str = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15'
    SET @delimiter = ','
    SET @xml = cast(('<X>'+replace(@str, @delimiter, '</X><X>')+'</X>') as xml)
    SELECT C.value('.', 'varchar(10)') as value FROM @xml.nodes('X') as X(C)
    

    OR

    DECLARE @str varchar(100), @delimiter varchar(10)
    SET @str = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15'
    SET @delimiter = ','
    ;WITH cte AS
    (
        SELECT 0 a, 1 b
        UNION ALL
        SELECT b, CHARINDEX(@delimiter, @str, b) + LEN(@delimiter)
        FROM CTE
        WHERE b > a
    )
    SELECT SUBSTRING(@str, a,
    CASE WHEN b > LEN(@delimiter) 
        THEN b - a - LEN(@delimiter) 
        ELSE LEN(@str) - a + 1 END) value      
    FROM cte WHERE a > 0
    

    Many more ways of doing the same is here How to split comma delimited string?

    0 讨论(0)
  • CREATE Function [dbo].[CsvToInt] ( @Array varchar(4000)) 
    returns @IntTable table 
    (IntValue int)
    AS
    begin
    declare @separator char(1)
    set @separator = ','
    declare @separator_position int 
    declare @array_value varchar(4000) 
    
    set @array = @array + ','
    
    while patindex('%,%' , @array) <> 0 
    begin
    
    select @separator_position = patindex('%,%' , @array)
    select @array_value = left(@array, @separator_position - 1)
    
    Insert @IntTable
    Values (Cast(@array_value as int))
    select @array = stuff(@array, 1, @separator_position, '')
    end
    
    0 讨论(0)
  • 2020-11-21 07:59

    You've tagged this SQL Server 2008 but future visitors to this question (using SQL Server 2016+) will likely want to know about STRING_SPLIT.

    With this new builtin function you can now just use

    SELECT TRY_CAST(value AS INT)
    FROM   STRING_SPLIT ('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15', ',') 
    

    Some restrictions of this function and some promising results of performance testing are in this blog post by Aaron Bertrand.

    0 讨论(0)
提交回复
热议问题