【问题标题】:Using a comma-separated parameter in an IN clause在 IN 子句中使用逗号分隔的参数
【发布时间】:2015-02-20 18:04:32
【问题描述】:

我有来自 SSRS 的 'param1, param2, parma3' 作为 varchar 参数的存储过程:我需要在查询的 IN 子句中使用它,但首先需要像这样更改其格式:

select *
from table1
where col1 in('param1', 'param2', 'param3')

在不创建函数和参数表的情况下重新格式化参数的最佳方法是什么?

【问题讨论】:

标签: sql tsql stored-procedures reporting-services parameters


【解决方案1】:

试试这个,只需要在@params字符串的开头和结尾添加逗号。

Declare @params varchar(100) Set @params = ',param1,param2,param3,'

Select * from t
where CHARINDEX(','+cast(col1 as varchar(8000))+',', @params) > 0

SQL FIDDLE

【讨论】:

【解决方案2】:

您可以使用拆分功能并按以下方式使用它 这里我的拆分 fnSplitString 返回拆分数据

select * from tb1 where id in(select splitdata from dbo.fnSplitString((select col1 from tb12 where id=3),','))


create FUNCTION [dbo].[fnSplitString] 
( 
    @string NVARCHAR(MAX), 
    @delimiter CHAR(1) 
) 
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
) 
BEGIN 
    DECLARE @start INT, @end INT 
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
    WHILE @start < LEN(@string) + 1 BEGIN 
        IF @end = 0  
            SET @end = LEN(@string) + 1

        INSERT INTO @output(splitdata)  
        VALUES(SUBSTRING(@string, @start, @end - @start)) 
        SET @start = @end + 1 
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END 
    RETURN 
END

【讨论】:

  • OP 的问题是“什么是在不创建函数和参数表的情况下重新格式化参数的最佳方法”。鉴于此,我假设他们知道这种方法,但不想创建一个例如fnSplitString 函数。这也是这个问题与 other similar questions 的不同之处。
【解决方案3】:

如果你使用的是 SQL 2016 及以上版本string_split你可以使用。

-- @param is where you keep your comma separated values example: 
declare @param = 'param1,param2,param3'
select * from table1 where col1 in (select TRIM(value) from string_split(@param,',')

关于string_split检查的更多信息offical documemt

此外,TRIM() 用于修剪空格中的值。

【讨论】:

    【解决方案4】:

    “最佳方式”是有争议的,但没有“创建函数和表参数”的一种经典方法是在存储过程中简单地使用动态 SQL:

    -- FORNOW: local to act as the SP param and arg
    declare @values varchar(100) = 'param1, param2, param3'
    
    -- Add opening and closing single quotes, then quotes around each
    -- comma-separated list item.
    select @values = '''' + REPLACE(@values, ', ', ''', ''') + ''''
    
    -- FORNOW: for clarity/debugging
    print @values
    --'param1', 'param2', 'param3'
    
    -- Run the desired query as dynamic SQL.
    DECLARE @sql as nvarchar(250);
    SET @sql = 'select * from table1 where col1 in (' + @values + ')';
    
    EXEC sp_executesql @sql;
    

    不过,这假设了几件事:

    1. 值列表中的逗号后跟一个空格。此解决方案的变体当然可以解决这方面的偏差,但重要的是要了解这一假设。
    2. 逗号分隔的值本身没有逗号 - 不太可能但值得一提,因为有时会忽略值是否满足此约束。

    【讨论】:

      【解决方案5】:

      我们可以在 SQL SERVER 中使用STRING_SPLIT()

      DECLARE @params varchar(max)= 'param1,param2,param3'
      
      SELECT *
      FROM table1
      WHERE col1 IN (SELECT value FROM STRING_SPLIT( @params , ','))
      

      【讨论】:

        【解决方案6】:

        将参数加载到字符串中并作为 sql 执行:

        declare @param varchar(1000) = 'param1, param2, parma3'
        declare @sql varchar(4000)
        select @sql = 
        'select *
        from table1
        where col1 in(''' + replace(@param,',',''',''') + ''')'
        
        -- print @sql -- to see what you're going to execute
        exec sp_executesql @sql
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-05-15
          • 1970-01-01
          • 2013-08-03
          • 1970-01-01
          • 1970-01-01
          • 2013-06-04
          • 1970-01-01
          相关资源
          最近更新 更多