将Csv字符串转换为表格并获取位置

时间:2018-04-20 19:30:46

标签: sql-server tsql

以下代码将CSV字符串转换为具有原始订单的表格(订单在Pos列中返回。)

declare @input nvarchar(max) = 'x,y,z';

declare @x xml = '<s>' + replace(@input, ',', '</s><s>') + '</s>';

select  c.value('.', 'nvarchar(max)') Col, identity(int) Pos
into    #t
from    @x.nodes('/s') x ( c );

select * from #t;
drop table #t

返回

Col Pos
y   1
x   2
z   3

有两个问题

  1. Pos不对,y得1,x得2。
  2. identity(int)需要select into
  3. 对于&#39; z,y,x&#39;的输入,z,y和x应分别得到1,2和3。

1 个答案:

答案 0 :(得分:3)

这根本不保证稳定:

declare @input nvarchar(max) = 'x,y,z';
declare @x xml = '<s>' + replace(@input, ',', '</s><s>') + '</s>';

select  c.value('.', 'nvarchar(max)') Col, 
        ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS pos
from    @x.nodes('/s') x ( c )
OPTION (MAXDOP 1);

<强> DBFiddle Demo

  1. 禁用并行性
  2. Identity(int) - &gt; ROW_NUMBER
  3. Modified split function

    CREATE FUNCTION dbo.Split(@origString varchar(max), @Delimiter char(1))     
    returns @temptable TABLE (pos INT IDENTITY(1,1), 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('z,y,x', ',');
    

    <强> DBFiddle Demo2