代码之家  ›  专栏  ›  技术社区  ›  Paul Fryer

在TSQL中将CSV字符串转换为表的最简洁的方法是什么?

  •  6
  • Paul Fryer  · 技术社区  · 15 年前
    -- Given a CSV string like this:
    
    declare @roles varchar(800)
    select  @roles = 'Pub,RegUser,ServiceAdmin'
    
    -- Question: How to get roles into a table view like this:
    
    select  'Pub'
    union
    select  'RegUser'
    union
    select  'ServiceAdmin'
    

    declare @rolesSql varchar(800)
    select  @rolesSql = 'select ''' + replace(@roles, ',', ''' union select ''') + ''''
    exec(@rolesSql)
    
    5 回复  |  直到 15 年前
        1
  •  15
  •   Community CDub    8 年前

    看看我的答案 here

    但基本上你会:

    CREATE FUNCTION dbo.Split(@origString varchar(max), @Delimiter char(1))     
    returns @temptable TABLE (items varchar(max))     
    as     
    begin     
        declare @idx int     
        declare @split varchar(max)     
    
        select @idx = 1     
            if len(@origString )<1 or @origString is null  return     
    
        while @idx!= 0     
        begin     
            set @idx = charindex(@Delimiter,@origString)     
            if @idx!=0     
                set @split= left(@origString,@idx - 1)     
            else     
                set @split= @origString
    
            if(len(@split)>0)
                insert into @temptable(Items) values(@split)     
    
            set @origString= right(@origString,len(@origString) - @idx)     
            if len(@origString) = 0 break     
        end 
    return     
    end
    

    Select * From dbo.Split(@roles, ',')
    
        2
  •  14
  •   Sayan Pal    8 年前

    如果您使用的是SQL Server兼容级别130,那么STRING\u SPLIT函数现在是可用的最简洁的方法。

    https://msdn.microsoft.com/en-gb/library/mt684588.aspx

    用法:

    SELECT * FROM string_split('Pub,RegUser,ServiceAdmin',',')
    
    RESULT:
    
    value
    -----------
    Pub
    RegUser
    ServiceAdmin
    
        3
  •  5
  •   LukeH    15 年前

    下面详细讨论您的选择:

        4
  •  1
  •   mattmc3    7 年前

    -- Given a CSV string like this:
    declare @roles varchar(800)
    select  @roles = 'Pub,RegUser,ServiceAdmin'
    
    -- Here's the XML way
    select split.csv.value('.', 'varchar(100)') as value
    from (
         select cast('<x>' + replace(@roles, ',', '</x><x>') + '</x>' as xml) as data
    ) as csv
    cross apply data.nodes('/x') as split(csv)
    

    如果您使用的是SQL 2016+,则使用 string_split 更好,但在SQL 2016之前,这是一种常见的方法。

        5
  •  1
  •   Marrt    5 年前

    在本例中,我所做的只是使用一些字符串替换将其转换为json,并像打开表一样打开json。可能不适用于所有用例,但运行起来非常简单,可以处理字符串和文件。对于文件,您只需要观察换行符,我发现它主要是“Char(13)+Char(10)”

    declare @myCSV nvarchar(MAX)= N'"Id";"Duration";"PosX";"PosY"
    "•P001";223;-30;35
    "•P002";248;-28;35
    "•P003";235;-26;35'
    
    --CSV to JSON
        --convert to json by replacing some stuff
        declare @myJson nvarchar(MAX)= '[['+  replace(@myCSV, Char(13)+Char(10), '],[' )  +']]'
            set @myJson = replace(@myJson, ';',',')         -- Optional: ensure coma delimiters for json if the current delimiter differs
        --  set @myJson = replace(@myJson, ',,',',null,')   -- Optional: empty in between
        --  set @myJson = replace(@myJson, ',]',',null]')   -- Optional: empty before linebreak
        
    SELECT
        ROW_NUMBER() OVER (ORDER BY (SELECT 0))-1 AS LineNumber, *
        FROM   OPENJSON( @myJson ) 
        with (
             col0   varchar(255)    '$[0]'
            ,col1   varchar(255)    '$[1]'
            ,col2   varchar(255)    '$[2]'
            ,col3   varchar(255)    '$[3]'
            ,col4   varchar(255)    '$[4]'
            ,col5   varchar(255)    '$[5]'
            ,col6   varchar(255)    '$[6]'
            ,col7   varchar(255)    '$[7]'
            ,col8   varchar(255)    '$[8]'  
            ,col9   varchar(255)    '$[9]'
            --any name column count is possible
        ) csv
        order by (SELECT 0) OFFSET 1 ROWS --hide header row