【问题标题】:How to parse a comma-delimited string variable in SQL如何在 SQL 中解析逗号分隔的字符串变量
【发布时间】:2015-02-17 20:12:10
【问题描述】:

我在 SQL Server 2008 中工作。我有一个带有参数的存储过程,称为@test。这个参数是 varchar(255)。在这个存储过程中,我需要解析这个字符串,将每个值转换为一个字符串本身(会有可变数量的值),并构建一个列表以在 NOT IN 语句中使用。

例如,假设@test = 'a, b, c, d'。我需要将此参数发送到我的存储过程中。在我的存储过程中有一个使用 NOT IN 语句的 SELECT 查询。对于这个例子,我需要这个 NOT IN 语句来读取 NOT IN('a', 'b', 'c', 'd')。

我该如何做到这一点?或者,这是一种不好的做法吗?

【问题讨论】:

标签: sql-server


【解决方案1】:

您可以在整个字符串中找到分隔符为逗号 (,) 的字符或字符串

DECLARE @code VARCHAR(50) = 'c', @text varchar(100) = 'a,b,c,d,e'

SELECT CHARINDEX(',' + @code + ',', ',' + @text + ',') > 0                             

【讨论】:

    【解决方案2】:

    使用 Split 函数和 NOT EXISTS 运算符几乎总是比 NOT IN 运算符快

    分割函数

    CREATE FUNCTION [dbo].[split]
        (
          @delimited NVARCHAR(MAX),
          @delimiter NVARCHAR(100)
        ) 
     RETURNS @t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))
    AS
    BEGIN
      DECLARE @xml XML
      SET @xml = N'<t>' + REPLACE(@delimited,@delimiter,'</t><t>') + '</t>'
    
      INSERT INTO @t(val)
      SELECT  r.value('.','varchar(MAX)') as item
      FROM  @xml.nodes('/t') as records(r)
      RETURN
    END
    

    测试数据

    DECLARE @Table TABLE (Vals INT)
    INSERT INTO @Table VALUES (1), (2), (3), (4)
    
    DECLARE @test VARCHAR(256) = '3,4,5,6'
    
    SELECT * FROM @Table 
    WHERE NOT EXISTS (SELECT 1
                      FROM [dbo].[split](@test , ',')
                      WHERE val = Vals)
    

    结果

    Vals
      1 
      2
    

    【讨论】:

      【解决方案3】:

      您可以为此使用动态 sql。使用替换函数获取正确的NOT IN() 参数:

      DECLARE @test VARCHAR(10) = 'a,b,c,d'
      
      DECLARE @sql NVARCHAR(MAX)
      
      SELECT @sql = 'SELECT *
      FROM #temp
      WHERE label NOT IN (''' + REPLACE( @test ,',',''',''') + ''')'
      
      EXEC sp_executesql @sql
      

      【讨论】:

        猜你喜欢
        • 2011-10-25
        • 2013-06-11
        • 2021-11-01
        • 2011-02-20
        • 2017-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多