在Reporting Services中为单个parameter passing多个值

我在报告中有几个多选参数。 我试图find一种方法来传递在Web查询string中的单个参数的多个值? 如果我传入一个值,它工作正常。

报告运行良好,为单个参数select多个选项。 我的麻烦在于networking查询string。

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

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

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

 where yourColumn in (@<your param name>) 

这是我将多选parameter passing给另一个多选参数时所使用的。

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

这是SQL Reporting Services中支持不足的function之一。

你需要做的是将所有select的项目作为单个string传递给存储过程。 string中的每个元素将用逗号分隔。

然后我做的是使用返回所提供的string作为表的函数分割string。 见下文。

 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,',')) 

我希望你find这个解决scheme是有用的。 请随时提出您可能有的任何问题。

干杯,约翰

John Sansom和Ed Harper有很好的解决scheme。 但是,在处理ID字段(即整数)时,我无法让它们工作。 我修改了下面的拆分函数,将这些值作为整数CAST,以便将表与主键列连接起来。 我还评论了代码,并添加了一个订单栏,以防分隔列表顺序显着。

 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 

如前所述,使用此function:

 WHERE id IN (SELECT Number FROM dbo.fn_SplitInt(@sParameterString,',')) 

ORACLE:

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

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

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

  INSTR(:name, TABLE.FILENAME) > 0 

我遇到了一个问题,否则精彩的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 

伟大的约翰解决scheme的修改,解决:

  • “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
    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 

只是一个评论 – 我碰到了一个让IN子句与Oracle 10g连接的世界。 我不认为重写的查询可以正确传递到一个10GB的数据库。 我必须完全放弃多重价值。 只有当select了单个值(来自多值参数select器)时,查询才会返回数据。 我尝试了与MS和Oracle驱动程序相同的结果。 我很想听听有没有人有这个成功。

  1. 为报表中的列表创build数据集
  2. 右键单击该参数并select可用的值
  3. select新创build的数据集作为数据集
  4. 将传递给存储过程的值作为值字段添加
  5. 将参数的描述添加到标签字段(如果参数是customerID,则标签可以是CustomerName ex。)
  6. 最后,将下面的代码添加到您的存储过程

声明@paramName AS NVARCHAR(500),

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

这对我很好:

 WHERE CHARINDEX(CONVERT(nvarchar, CustNum), @CustNum) > 0 

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

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

 ="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] + '%' 

我很想找出一种方法来做到这一点没有dynamic的SQL,但我不认为这会工作,因为SSRS将parameter passing给实际查询的方式。 如果有人知道更好,请让我知道。

如果要通过查询string将多个值传递给RS,则只需为每个值重复报告参数即可。

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

 &rp:COLS=1&rp:COLS=1&rp:COLS=5 etc.. 

你也可以做的是在存储过程中添加下面的代码:

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

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

我是这个网站的新手,不知道如何评论以前的答案,这是我应该做的。 我也无法投票杰夫的post,我相信给了我我的答案。 无论如何…

虽然我可以看到一些优秀的post和后来的调整是如何工作的,但我只能读取数据库,所以没有UDF,SP或基于视图的解决scheme。 所以Ed Harper的解决scheme看起来不错,除了VenkateswarluAvula的评论,你不能将逗号分隔的string作为parameter passing给WHERE IN子句,并期望它能够按照你的需要工作。 但Jeff对ORACLE 10g的解决scheme填补了这一空白。 我把这些与罗素克里斯托弗的博客一起在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和我有我的解决scheme:

创build你的多选参数MYPARAMETER使用任何可用的值来源(可能是一个数据集)。 在我的情况下,多选是来自一堆TEXT条目,但我相信一些调整它可以与其他types的工作。 如果您要将“全选”设置为默认位置,请将默认位置设置为相同的源。 这给你你的用户界面,但创build的参数不是传递给我的SQL的参数。

跳到SQL的前面,Jeff的解决scheme在WHERE IN(@MYPARAMETER)问题,我有一个问题,我自己的一个值('Charge')出现在其中一个值('Non Charge' ),这意味着CHARINDEX可能会发现一个假阳性。 我需要在前后search参数的分隔值。 这意味着我需要确保逗号分隔的列表也有一个领先和trailing逗号。 这是我的SQL片段:

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

中间的位是创build另一个参数(隐藏在生产中,但不是在开发过程中):

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

它是传递给SQL的这个参数,它恰好是一个可search的string,但是像任何文本那样处理SQL。

我希望把这些答案片段放在一起帮助别人find他们想找的东西。

在过去,我采取了使用存储过程和一个函数来selectSQL Server查询多年报告服务。 在Ed Harperbuild议的查询参数值中使用Joinexpression式仍然不能在where语句中使用SQL IN子句。 我的解决方法是在where子句中使用以下参数和expression式:charindex(cast(Schl.Invt_Yr as char(4)),@Invt_Yr)> 0

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

我刚刚完成了一个报告,要求必须保存参数,并且再次打开报告(报告通过OrderID参数)时,必须再次select用户先前select的值。

该报告使用了十几个参数,每个参数都有自己的数据集和结果下拉列表。 这些参数依赖于以前的参数来缩小最终select的范围,并且当报告被“查看”时,存储过程被调用来填充。

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

报表运行时,会出现一个数据集dsParameters,它是SQL文本,如果有的话,则会为该订单IDselect单个行。 报告中的每个参数都将从此数据集中获取其默认值,并从专用于该参数的数据集中获取其select列表。

我遇到了多选参数的麻烦。 我在主数据集参数列表中使用了连接(@Value,“,”)命令,传递给存储过程一个逗号分隔的string。 但是如何恢复呢? 您不能将逗号分隔的string反馈回参数的默认值框。

我不得不创build另一个数据集来拆分参数,与您所谈论的方式类似。 它看起来像这样:

 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 

每次打开表单时,此数据集都会检查数据库中是否存在此多值参数的保存string。 如果没有,则返回null。 如果有,则parsing出逗号并为每个值创build一行。

然后默认值框被设置为这个数据集,和fldDesc。 有用! 当我select一个或多个,他们保存和补充时,再次打开表格。

我希望这有帮助。 我search了一会儿,没有发现任何关于在数据库中保存连接string,然后parsing出来的数据集。

所以乘以文本值将最终在每个我用= join(Parameters!Customer.Value,“','”)周围的单引号的查询。 所以在“.Value”后面加逗号,双引号,单引号,逗号,单引号,双引号,括号。 简单:)

我需要甲骨文的解决scheme,我发现这在我的查询DB> = 10g我的报告内工作。

selectregexp_substr(,'[^,] +',1,level)从双连接通过regexp_substr(,'[^,] +',1,level)

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