【问题标题】:Read comma separated string in Sql server in loop在循环中读取 Sql server 中的逗号分隔字符串
【发布时间】:2017-07-07 13:19:37
【问题描述】:

我有这样的 nvarchar 数据:

'20030,20031,20033,20034,20065,20045,20044'

我想通过拆分成数组来读取所有这些,或者在拆分过程中一个一个地读取并做进一步的处理。

我已经尝试过这个good article 但无法做到。

【问题讨论】:

  • 不能怎么办?你有没有尝试过?发布您的代码和任何错误?
  • 不知道答案的请不要投反对票请在评论中说出我犯的错误或给出答案的人已经犯了如果你不能请不要投票否决。谢谢
  • @padhiyar : 试试我的答案,让我知道它是否有效
  • @padhiyar - 阅读本文以了解如何在网站上发布问题。否则它们将被关闭:stackoverflow.com/help/mcve
  • 我投了反对票,因为这个问题没有显示任何研究工作。您链接了一篇文章,但没有解释为什么您无法使用该文章来解决您的问题,或者为什么互联网上的任何其他文章都无法帮助您。这是一个很常见的问题,不需要在 Stack Overflow 上再提问。

标签: sql-server split nvarchar


【解决方案1】:

试试这个article 使用函数来读取逗号分隔的值并返回表格

CREATE FUNCTION dbo.Split(@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (Items nvarchar(4000))
AS
BEGIN
DECLARE @INDEX INT
DECLARE @SLICE nvarchar(4000)
-- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
--     ERO FIRST TIME IN LOOP
SELECT @INDEX = 1
WHILE @INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF @INDEX !=0
SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
ELSE
SELECT @SLICE = @STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO @Results(Items) VALUES(@SLICE)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
-- BREAK OUT IF WE ARE DONE
IF LEN(@STRING) = 0 BREAK
END
RETURN
END

只需从存储过程中调用该函数或仅调用如下函数:

SELECT items FROM [dbo].[Split] ('20030,20031,20033,20034,20065,20045,20044', ',') 

【讨论】:

    【解决方案2】:

    一点都不难。最好用递归来解决

    create table #Testdata2(Data varchar(max))
    insert #Testdata2 select '20030,20031,20033,20034,20065,20045,20044'
    
    
    
    ;with tmp(DataItem, Data) as (
    select LEFT(Data, CHARINDEX(',',Data+',')-1),
        STUFF(Data, 1, CHARINDEX(',',Data+','), '')
    from #Testdata2
    union all
    select LEFT(Data, CHARINDEX(',',Data+',')-1),
        STUFF(Data, 1, CHARINDEX(',',Data+','), '')
    from tmp
    where Data > ''
    )
    select DataItem
    from tmp
    OPTION (maxrecursion 0)
    

    输出:

    (select)
     Data
     ----------------
     20030,20031,20033,20034,20065,20045,20044
    
    
    (query)
    DataItem
    ----------------
    20030
    20031
    20033
    20034
    20065
    20045
    20044
    

    【讨论】:

    • @Milney :感谢您的知识。请分享一些文章来证明你的话?另外,如果您有解决方案,请告诉我们。很想找到替代方法
    • 是的。这是一个:sqlperformance.com/2012/07/t-sql-queries/split-strings如果你只是google t-sql split string 有很多...
    • 未来提示:递归解决方案很少是解决问题的最佳方法
    • 谢谢。虽然它并没有说 CTE 的性能很差。我相信我已经使用 CTE 和递归,这不是很糟糕的方法。
    • @PrabhatG 我有一个与你的非常相似的拆分功能,我对它(和我自己)很满意......但是,我对计数方法的性能感到惊讶。下面将演示一个tally和一个xml方法stackoverflow.com/questions/43082763/…...看一看,
    【解决方案3】:

    另一种使用字符串拆分和 Xml 的方法

    DECLARE @string nvarchar(max)='20030,20031,20033,20034,20065,20045,20044'
    DECLARE @Table AS TABLE (String nvarchar(max))
    INSERT INTO @Table
    SELECT @string
    
    SELECT Row_NUmber ()OVER(ORDER BY (SELECT 1) )AS Seq, Split.a.value('.', 'VARCHAR(1000)') AS String
                FROM  (
                    SELECT   CAST('<S>' + REPLACE(String, ',', '</S><S>') + '</S>' AS XML) AS String
                    FROM @Table
                    ) AS A
                CROSS APPLY String.nodes('/S') AS Split(a) 
    

    上面的代码可以合并到函数中返回分割字符串

    CREATE FUNCTION dbo.udf_Split (
        @String NVARCHAR(4000)
        ,@Delimiter CHAR(1)
        )
    RETURNS @Results TABLE (Items NVARCHAR(4000))
    AS
    BEGIN
        DECLARE @Table AS TABLE (String NVARCHAR(max))
    
        INSERT INTO @Table
        SELECT @String
    
        INSERT INTO @Results
        SELECT Split.a.value('.', 'VARCHAR(1000)') AS String
        FROM (
            SELECT CAST('<S>' + REPLACE(String, @Delimiter, '</S><S>') + '</S>' AS XML) AS String
            FROM @Table
            ) AS A
        CROSS APPLY String.nodes('/S') AS Split(a)
    
        RETURN
    END
    
    SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1))AS Seq,
        * FROM dbo.udf_Split('20030,20031,20033,20034,20065,20045,20044',',')
    

    结果

    Seq String
    ----------
    1   20030
    2   20031
    3   20033
    4   20034
    5   20065
    6   20045
    7   20044
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-13
      • 1970-01-01
      • 2014-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多