SSRS参数。允许“全部”或“空”

时间:2010-07-27 13:44:49

标签: tsql reporting-services ssrs-2008 reportingservices-2005

SSRS参数很痛苦。我希望能够通过允许用户访问许多不同的参数并使其成为可选参数来重用报告以满足许多不同的需求。

所以,如果我开始使用代码如:

Select * from mytable myt
where myt.date between '1/1/2010' and '12/31/2010'
and year(myt.date) = '2010'
and myt.partnumber = 'XYZ-123' 

我希望这些参数是可选的,所以我的第一次尝试是将参数默认为null,例如:

and (myt.partnumber = (@PartNumber) or (@PartNumber) is null)

这有问题,因为如果有问题的数据库字段可以为空,那么您将删除记录,因为null不等于null。

然后我使用了这样的代码:

DECLARE @BeginDate AS DATETIME
DECLARE @EndDate AS DATETIME
DECLARE @PartNumber AS VARCHAR(25)
SET @Year = '..All'
SET @BeginDate = '1/1/2005'
SET @EndDate = '12/31/2010'
SET @PartNumber = '..All'
SET @Year = '..All'

Select * from mytable myt
where (myt.date between (@BeginDate) and (@EndDate))
and (year(myt.date) =  (@Year) or (@Year) = '..All' )
and (myt.partnumber = (@PartNumber) or (@PartNumber) = '..All')

这不起作用,因为Year(myt.date)是一个整数而@Year不是。

所以,这是我的问题。

  1. 如何使我的日期可选?简单地将它们默认为超出实际范围的日期是最好的方法,所以我返回所有值?
  2. 处理null或'..All'选项以使我的查询尽可能可读并允许我的用户拥有大多数数据类型的可选参数的最佳方法是什么?
  3. 我宁愿不使用null

3 个答案:

答案 0 :(得分:3)

继续并允许空值,这表示不应该应用过滤器。然后,您可以使用以下内容:

SELECT *
FROM mytable myt
WHERE COALESCE(myt.date, '1/1/1900') between COALESCE(@BeginDate, myt.date, '1/1/1900') and COALESCE(@EndDate, myt.date, '1/1/1900')
    AND COALESCE(YEAR(myt.date), -1) = COALESCE(@Year, YEAR(myt.date), -1)
    AND COALESCE(myt.partnumber, -1) = COALESCE(@PartNumber, myt.partnumber, -1)

总之,如果任何变量值为NULL,则将列值与自身进行比较,这有效地忽略了条件。更具体地说,在测试myt.date时,如果@BeginDate为NULL,则将较低范围值设置为等于myt.date值。使用@EndDate值进行相同的替换。即使如果@BeginDate@EndDate都为NULL,条件也将为真。

YEAR(myt.date)myt.partnumber使用了类似的方法。如果变量值为NULL,则将列值与自身进行比较,该值始终为真。

更新: 为每个COALESCE添加了一个默认值,以处理列值为NULL的情况。

答案 1 :(得分:1)

我喜欢你的第三个代码块。看起来您的WHERE子句可以更正为使用非int值。年份行的AND子句看起来像这样 - 不是我最好的T-SQL,但它应该让你指向正确的方向:

and 1 = CASE @Year WHEN '..All' THEN 1 ELSE CASE WHEN year ( myt.date )  = CONVERT ( int, @Year ) THEN 1 ELSE 0 END END

这将允许您具有字符串值'..All'或int值。要么正确匹配。您可以使用partnumber执行相同的操作。

答案 2 :(得分:0)

尝试这样,关键是要修复你的空参数值以代替空值,因为sql server支持短路评估,把null检查通常应该表现得更好。

Select * from mytable myt
where (myt.date between (@BeginDate) and (@EndDate))
and (@Year IS NULL OR COALESCE(myt.date,'1900') = @Year)
and (@PartNumber IS NULL OR ISNULL(myt.partnumber, '<NULL>') = (@PartNumber)