在SQL查询中使用SSRS多值参数,而不使用IN运算符

时间:2013-12-15 05:52:02

标签: sql sql-server sql-server-2008 reporting-services

我必须将多个值(例如:Year1,year2,year3等)传递给同一个查询,但我不能使用IN条件,因为我在大多数情况下使用小于或等于。我可以通过在不更改查询的情况下在同一参数中传递多个值来实现此目的吗?

是否可以从SSRS参数中获取多个值并将它们传递给查询以获取输出:

Year1           Year2           Year3
Value(output)   Value(output)   Value(output) 

2 个答案:

答案 0 :(得分:1)

您可以将多值参数作为逗号分隔的字符串传递,但您的SQL查询将需要更新以处理该CSV字符串。要将多值参数作为CSV字符串传递,您将打开数据集属性并转到参数选项卡。然后将参数的值设置为此表达式:

=JOIN(Parameters!MultiValueYearParameter.Value,",")

这将将多值参数中的所有值连接在一起,并使用逗号作为分隔符。然后,您可以使用下面的split函数处理它(或者只是修改它以在SQL中内联工作,如果您不能或不需要创建单独的函数来执行此操作)。

Split Function for T-SQL using FOR XML上的这篇博文显示了如何在不使用字符串解析或while循环的情况下执行此操作。字符串解析容易出错并且不可扩展,而且只要有可能就在SQL中避免循环。

下面我修改了分割函数,以返回DATE值的表,然后您可以在INNER JOIN中使用这些表来使用您喜欢的任何运算符过滤您的查询。

--this is the parameter passed from the report
--(the date strings may not be formatted this way. do not try to rely on that)
DECLARE @YearParameter VARCHAR(MAX) = '2014-01-01,2011-12-02,2015-10-22';


--use this to do the xml parsing
declare @xml xml = N'<root><r>' + replace(@YearParameter,',','</r><r>') + '</r></root>'

--create a table variable to store the date values
DECLARE @dateValues TABLE (val DATE);

--parse the xml/csv string and cast the results to a DATE and insert into the table var
INSERT INTO @dateValues
select CAST(r.value('.','varchar(max)') AS DATE) AS val
from @xml.nodes('//root/r') as records(r);

然后,您可以使用该表变量来过滤SQL查询。我给出了一个如何在下面使用它的例子。

在示例中,我创建了一个包含开始日期和结束日期的行表。然后我过滤该表以仅显示参数值在开始日期和结束日期之间的行。

DECLARE @testTable TABLE (Descript VARCHAR(25), startDate DATE, endDate DATE);
INSERT INTO @testTable (Descript, startDate, endDate)
    VALUES ('row1', '2014-05-01','2014-08-01'), ('row2', '2013-10-01','2014-01-10'), ('row3', '2015-10-01','2015-12-15'),('row4','2013-01-01','2015-01-01'),
        --these rows won't appear in the result set
            ('row5','2010-01-01','2010-06-01'), ('row6','2013-12-25','2014-05-20');


-- get all rows from the test table where a selected parameter value
-- is between the start and end dates.
SELECT *
FROM @testTable AS tbl
WHERE EXISTS (
    SELECT *
    FROM @dateValues
    WHERE val BETWEEN tbl.startDate AND tbl.endDate
);

答案 1 :(得分:0)

在SSRS中,您可以构建表格和复杂的解决方案。 在“文本查询报告”构建器中,此处是拆分参数以获取三个日期的示例。

BEGIN 

/* suppose the inbound pram is a string with 10 places per date '01/01/2010,11/12/2012,05/06/2013' */
/* you could also nip the string apart by each comma... */

DECLARE @YEAR1 DATETIME 
DECLARE @YEAR2 DATETIME 
DECLARE @YEAR3 DATETIME

SET  @YEAR1 = CAST(SUBSTRING(@INBOUNDPARAM, 1, 10) AS DATETIME)
SET  @YEAR2 = CAST(SUBSTRING(@INBOUNDPARAM, 12, 10) AS DATETIME)
SET  @YEAR3 = CAST(SUBSTRING(@INBOUNDPARAM, 23, 10) AS DATETIME)

SELECT  @YEAR1 AS Year1, @YEAR2 AS Year2, @YEAR3 AS Year3

END

当然,日期年份仅为年份(@ Year1)= 2010年......