70

我的报告中有几个多选参数。我正在尝试找到一种方法来为 Web 查询字符串中的单个参数传递多个值?如果我传入一个值,它工作正常。

该报告运行良好,为单个参数选择多个选项。我的麻烦在于网络查询字符串。

4

21 回答 21

102

尽管 John Sansom 的解决方案有效,但还有另一种方法可以做到这一点,而不必使用可能效率低下的标量值 UDF。在 SSRS 报告中,在查询定义的参数选项卡上,将参数值设置为

=join(Parameters!<your param name>.Value,",")

在您的查询中,您可以像这样引用该值:

where yourColumn in (@<your param name>)
于 2009-02-06T08:42:32.313 回答
47

这是我在将多选参数传递给另一个多选参数时使用的。

=SPLIT(JOIN(Parameters!<your param name>.Value,","),",")
于 2009-03-18T22:54:39.387 回答
20

这是 SQL Reporting Services 中支持较差的功能之一。

您需要做的是将所有选定的项目作为单个字符串传递给您的存储过程。字符串中的每个元素都将用逗号分隔。

然后我要做的是使用将提供的字符串作为表返回的函数来拆分字符串。见下文。

ALTER FUNCTION [dbo].[fn_MVParam]
   (@RepParam nvarchar(4000), @Delim char(1)= ',')
RETURNS @Values TABLE (Param nvarchar(4000))AS
  BEGIN
  DECLARE @chrind INT
  DECLARE @Piece nvarchar(100)
  SELECT @chrind = 1 
  WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR))
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam) - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
  RETURN
  END

然后,您可以在主查询的 where 子句中引用结果,如下所示:

where someColumn IN(SELECT Param FROM dbo.fn_MVParam(@sParameterString,','))

我希望你发现这个解决方案很有用。请随时提出您可能有的任何问题。

干杯,约翰

于 2009-02-04T17:08:43.497 回答
9

John Sansom 和 Ed Harper 有很好的解决方案。但是,在处理 ID 字段(即整数)时,我无法让它们工作。我修改了下面的拆分函数,将值转换为整数,以便表将与主键列连接。我还注释了代码并添加了一个顺序列,以防分隔列表顺序很重要。

CREATE FUNCTION [dbo].[fn_SplitInt]
(
    @List       nvarchar(4000),
    @Delimiter  char(1)= ','
)
RETURNS @Values TABLE
(
    Position int IDENTITY PRIMARY KEY,
    Number int
)

AS

  BEGIN

  -- set up working variables
  DECLARE @Index INT
  DECLARE @ItemValue nvarchar(100)
  SELECT @Index = 1 

  -- iterate until we have no more characters to work with
  WHILE @Index > 0

    BEGIN

      -- find first delimiter
      SELECT @Index = CHARINDEX(@Delimiter,@List)

      -- extract the item value
      IF @Index  > 0     -- if found, take the value left of the delimiter
        SELECT @ItemValue = LEFT(@List,@Index - 1)
      ELSE               -- if none, take the remainder as the last value
        SELECT @ItemValue = @List

      -- insert the value into our new table
      INSERT INTO @Values (Number) VALUES (CAST(@ItemValue AS int))

      -- remove the found item from the working list
      SELECT @List = RIGHT(@List,LEN(@List) - @Index)

      -- if list is empty, we are done
      IF LEN(@List) = 0 BREAK

    END

  RETURN

  END

如前所述使用此功能:

WHERE id IN (SELECT Number FROM dbo.fn_SplitInt(@sParameterString,','))
于 2010-03-26T13:00:37.027 回答
5

甲骨文:

“IN”短语(Ed 的解决方案)不适用于 Oracle 连接(至少版本 10)。但是,发现了这个简单的解决方法。使用数据集的参数选项卡将多值参数转换为 CSV:

    :name =join(Parameters!name.Value,",")

然后在你的 SQL 语句的 WHERE 子句中使用 instring 函数来检查匹配。

    INSTR(:name, TABLE.FILENAME) > 0
于 2009-11-02T22:21:35.640 回答
4

我遇到了另一个很棒的 fn_MVParam 的问题。SSRS 2005 发送的数据带有撇号作为 2 个引号。

我添加了一行来解决这个问题。

select @RepParam = replace(@RepParam,'''''','''')

我的 fn 版本也使用 varchar 而不是 nvarchar。

CREATE FUNCTION [dbo].[fn_MVParam]
   (
    @RepParam varchar(MAX),
    @Delim char(1)= ','
   )
RETURNS @Values TABLE (Param varchar(MAX)) AS
/*
  Usage:  Use this in your report SP 
     where ID in (SELECT Param FROM fn_MVParam(@PlanIDList,','))
*/

BEGIN

   select @RepParam = replace(@RepParam,'''''','''')
   DECLARE @chrind INT
   DECLARE @Piece varchar(MAX)
   SELECT @chrind = 1
   WHILE @chrind > 0
      BEGIN
         SELECT @chrind = CHARINDEX(@Delim,@RepParam)
         IF @chrind > 0
            SELECT @Piece = LEFT(@RepParam,@chrind - 1)
         ELSE
            SELECT @Piece = @RepParam
         INSERT @VALUES(Param) VALUES(@Piece)
         SELECT @RepParam = RIGHT(@RepParam,DATALENGTH(@RepParam) - @chrind)
         IF DATALENGTH(@RepParam) = 0 BREAK
      END
   RETURN
END
于 2011-04-19T19:08:25.237 回答
3

修改伟大的约翰解决方案,解决:

  • “2 引号”错误
  • 参数中的一块后的空格

    
    ALTER FUNCTION [dbo].[fn_MVParam]
    (@RepParam nvarchar(4000), @Delim char(1)= ',')
    RETURNS @Values TABLE (Param nvarchar(4000))AS
    BEGIN
    //2 quotes error
    set @RepParam = replace(@RepParam,char(39)+char(39),CHAR(39))
    DECLARE @chrind INT
    DECLARE @Piece nvarchar(100)
    SELECT @chrind = 1 
    WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR(300)))
      //space after one of piece in parameter: LEN(@RepParam + '1')-1
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam + '1')-1 - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
    RETURN
    END
    
    
于 2012-02-03T12:53:50.763 回答
3

这适用于一组不同的字符串(例如“START”、“END”、“ERROR”、“SUCCESS”)

1)定义报告参数(例如@log_status)并检查“允许多个值”
在此处输入图像描述

2) 定义数据集
3) 打开数据集属性窗口
3a) 在查询选项卡中输入您的查询:例如

select * from your_table where (CHARINDEX(your_column, @log_status,0) > 0)

3b) 在参数选项卡中输入您的参数,例如
Parametername: @log_status ; Parametervalue: <<Expr>>
3c) 对于 Expr,单击“fx”按钮并输入:

=join(Parameters!log_status.Value,",")

在此处输入图像描述

完成的!(它类似于 Ed Harper 的解决方案,但很抱歉这对我不起作用)

于 2018-05-24T19:54:14.557 回答
3

从 MSSQL 2016 开始 - 兼容级别为 130,您可以利用String_Split()它来解析来自 SSRS 的连接参数。假设您想从 SSRS 中的查询中填充参数,然后将该参数传递给存储的过程或 SSRS 共享数据集:

  1. 将两个数据集添加到您的 SSRS 报告中,一个返回要在参数中显示的值和标签列表,另一个包含您要过滤的实际数据。这些数据集中的每一个都可以是存储过程或共享数据集或嵌入式查询。
  2. 在 SSRS 中创建一个不在您要过滤的数据集上的参数。让我们称之为Customer
  3. 设置参数以允许多个值,并使用要从查询中显示的数据集、标签和值Customer设置选项卡。Available Values
  4. 右键单击要过滤的数据集并添加在存储过程中定义的参数。让我们称之为CustomerList
  5. 单击此参数的值字段旁边的表达式按钮,然后执行Join(Parameters!Customer.Value, ",")
  6. 在您的存储过程或共享数据集中,利用 string_split 将逗号分隔的@CustomerList参数分解为一个数组: Customer.CustID in (select value from string_split(@CustomerList, ',') where value = Customer.CustID)
于 2019-04-23T14:48:32.690 回答
2

只是一个评论 - 我遇到了一个痛苦的世界,试图让一个 IN 子句在与 Oracle 10g 的连接中工作。我认为重写后的查询不能正确传递给 10g db。我不得不完全放弃多值。The query would return data only when a single value (from the multi-value parameter selector) was chosen. 我尝试了 MS 和 Oracle 驱动程序,结果相同。我很想知道是否有人在这方面取得了成功。

于 2009-02-07T17:33:52.303 回答
2
  1. 为报表中的列表创建数据集
  2. 右键单击参数并选择可用值
  3. 选择新创建的数据集作为数据集
  4. 将传递给存储过程的值作为值字段添加
  5. 将参数的描述添加到标签字段(如果参数是 customerID,则标签可以是 CustomerName ex。)
  6. 最后,将以下代码添加到您的存储过程

将@paramName 声明为 NVARCHAR(500),

IF RIGHT(@paramName, 1) = ',' BEGIN SET @paramName = LEFT((@paramName, LEN((@paramName)-1) END

于 2013-06-27T13:58:30.050 回答
2

首先将多个值添加到表中可能会更容易,然后您可以加入或任何您想要的(即使使用通配符)或将数据保存到另一个表以供以后使用(甚至将值添加到另一个表) .

通过数据集中的表达式设置参数值:

="SELECT DISTINCT * FROM (VALUES('" & JOIN(Parameters!SearchValue.Value, "'),('") & "')) 
AS tbl(Value)"

查询本身:

DECLARE @Table AS TABLE (Value nvarchar(max))

INSERT INTO @Table EXEC sp_executeSQL @SearchValue 

通配符示例:

SELECT * FROM YOUR_TABLE yt 

INNER JOIN @Table rt ON yt.[Join_Value] LIKE '%' + rt.[Value] + '%'

我很想找到一种无需动态 SQL 的方法,但由于 SSRS 将参数传递给实际查询的方式,我认为它不会起作用。如果有人知道更好,请告诉我。

于 2016-08-05T18:42:05.623 回答
1

您还可以在存储过程中添加以下代码:

set @s = char(39) + replace(@s, ',', char(39) + ',' + char(39)) + char(39)

(假设@s 是一个多值字符串(如“A,B,C”))

于 2010-12-13T15:12:24.333 回答
1

如果您想通过查询字符串将多个值传递给 RS,您需要做的就是为每个值重复报告参数。

例如; 我有一个名为 COLS 的 RS 列,该列需要一个或多个值。

&rp:COLS=1&rp:COLS=1&rp:COLS=5 etc..
于 2012-03-12T22:59:12.903 回答
1

我是该网站的新手,不知道如何评论以前的答案,我觉得这应该是。我也无法投票给 Jeff 的帖子,我相信这给了我答案。无论如何...

虽然我可以看到一些很棒的帖子和随后的调整是如何工作的,但我只有对数据库的读取权限,所以没有 UDF、SP 或基于视图的解决方案对我有用。所以 Ed Harper 的解决方案看起来不错,除了 VenkateswarluAvula 的评论,您不能将逗号分隔的字符串作为参数传递给 WHERE IN 子句并期望它按您的需要工作。但 Jeff 的 ORACLE 10g 解决方案填补了这一空白。我将这些与 Russell Christopher 的博文放在一起,网址为http://blogs.msdn.com/b/bimusings/archive/2007/05/07/how-do-you-set-select-all-as-the-default- for-multi-value-parameters-in-reporting-services.aspx我有我的解决方案:

使用任何可用值来源(可能是数据集)创建多选参数 MYPARAMETER。就我而言,多选来自一堆 TEXT 条目,但我确信通过一些调整它可以与其他类型一起使用。如果您希望全选为默认位置,请将相同的源设置为默认位置。这为您提供了您的用户界面,但创建的参数不是传递给我的 SQL 的参数。

跳到 SQL 和 Jeff 对 WHERE IN (@MYPARAMETER) 问题的解决方案,我自己有一个问题,其中 1 个值('Charge')出现在其他值之一('Non Charge' ),这意味着 CHARINDEX 可能会发现误报。我需要在参数之前和之后搜索分隔值。这意味着我需要确保逗号分隔的列表也有前导和尾随逗号。这是我的 SQL 片段:

where ...
and CHARINDEX(',' + pitran.LINEPROPERTYID + ',', @MYPARAMETER_LIST) > 0

中间的部分是创建另一个参数(在生产中隐藏,但在开发时不隐藏):

  • MYPARAMETER_LIST 的名称
  • 一种文本
  • 一个可用的值 ="," + join(Parameters!MYPARAMETER.Value,",") + ","和一个无关紧要的标签
    (因为它不会显示)。
  • 默认值完全相同
  • 可以肯定的是,我在两个参数的高级属性中都设置了始终刷新

正是这个参数被传递给 SQL,它恰好是一个可搜索的字符串,但 SQL 像处理任何文本一样处理它。

我希望将这些答案片段放在一起可以帮助人们找到他们正在寻找的东西。

于 2013-02-14T19:41:53.447 回答
1

过去,我曾求助于使用存储过程和函数在 SQL Server 查询中为报告服务选择多年。按照 Ed Harper 的建议在查询参数值中使用 Join 表达式,仍然无法在 where 语句中使用 SQL IN 子句。我的解决方案是在 where 子句中使用以下内容以及参数 Join 表达式:和 charindex (cast(Schl.Invt_Yr as char(4)) , @Invt_Yr) > 0

于 2013-03-20T19:25:30.560 回答
1

这是关于使用连接函数保存多值参数,然后稍后从数据库中恢复完全相同的选择。

我刚刚完成了一个要求必须保存参数的报表,当再次打开报表时(报表传递了一个 OrderID 参数),必须再次选择用户之前选择的值。

该报告使用了六个参数,每个参数都有自己的数据集和生成的下拉列表。这些参数依赖于先前的参数来缩小最终选择的范围,并且在“查看”报告时调用存储过程来填充。

存储过程接收从报告中传递给它的每个参数。它检查数据库中的存储表以查看是否为该 OrderID 保存了任何参数。如果没有,则保存所有参数。如果是这样,它会更新该订单的所有参数(这是用户稍后改变主意的情况)。

当报表运行时,有一个数据集 dsParameters,它是 SQL 文本,如果有,则选择该 orderID 的单行。报表中的每个参数都从该数据集中获取其默认值,并从专用于该参数的数据集中获取其选择列表。

我遇到了多选参数的问题。我在主数据集参数列表中使用了 join(@Value,",") 命令,将逗号分隔的字符串传递给存储过程。但是如何恢复呢?您不能将逗号分隔的字符串反馈回参数的默认值框。

我必须创建另一个数据集来拆分参数,其方式与您所说的类似。它看起来像这样:

IF OBJECT_ID('tempdb..#Parse','U') IS NOT NULL DROP TABLE #Parse

DECLARE @Start int, @End int, @Desc varchar(255)

SELECT @Desc = fldDesc FROM dbCustomData.dbo.tblDirectReferralFormParameters WHERE fldFrom = @From and fldOrderID = @OrderID

CREATE TABLE #Parse (fldDesc varchar(255))

SELECT @Start = 1, @End = 1

WHILE @End > 0
    BEGIN
        SET @End = CHARINDEX(',',@Desc,@Start)
        IF @End = 0 
            BEGIN
                INSERT #Parse SELECT REPLACE(SUBSTRING(@Desc,@Start,LEN(@Desc)),',','') AS fldDesc 
                BREAK
            END
        ELSE        
            BEGIN
                INSERT #Parse SELECT REPLACE(SUBSTRING(@Desc,@Start,@End-@Start),',','') AS fldDesc 
            END
        SET @Start = @End + 1
    END

SELECT * FROM #Parse

每次打开表单时,此数据集都会检查数据库中保存的该多值参数的字符串。如果没有,则返回 null。如果打开,它会解析逗号并为每个值创建一行。

然后将默认值框设置为此数据集和 fldDesc。有用!当我选择一个或多个时,它们会在再次打开表单时保存并补充。

我希望这有帮助。我搜索了一段时间,没有发现将连接字符串保存在数据库中然后在数据集中解析出来的任何提及。

于 2013-05-03T23:34:58.613 回答
1

这对我很有用:

WHERE CHARINDEX(CONVERT(nvarchar, CustNum), @CustNum) > 0
于 2014-05-29T15:28:36.833 回答
1

因此,乘以文本值将在查询中结束,每个我使用的单引号 =join(Parameters!Customer.Value,"','")。所以在“.Value”之后就是逗号,双引号,单引号,逗号,单引号,双引号,右括号。简单的:)

于 2016-12-09T11:24:25.557 回答
1

以下解决方案对我有用。

  1. 在数据集属性的参数选项卡中,单击您需要允许逗号的参数旁边的表达式图标(! http://chittagongit.com//images/fx-icon/fx-icon-16.jpg [fx symbol])分隔条目。

  2. 在出现的表达式窗口中,使用拆分函数(通用函数 -> 文本)。示例如下所示:

=拆分(参数!参数名称。值,,,,)

于 2018-06-12T00:13:27.580 回答
0

我需要 Oracle 的解决方案,我发现这在我对 DB>=10g 报告的查询中对我有用。

select * from where in ( select regexp_substr(,'[^,]+', 1, level) from dual connect by regexp_substr(, '[^,]+', 1, level) 不为空);

来源 https://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement

于 2017-01-09T22:02:18.177 回答