【问题标题】:SSRS Parameters. Allowing "All" or "Null"SSRS 参数。允许“全部”或“空”
【发布时间】:2011-03-21 15:09:09
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

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

    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的情况。

    【讨论】:

    • 这不起作用,这是我尝试的第一件事(在问题中提到)。原因是如果我的一个字段可以为空并且包含空值,则不会返回记录.例如: AND myt.partnumber = COALESCE(@PartNumber, myt.partnumber) 如果 myt.partnumber 和 @PartNumber 都为 null,则连接不会返回该记录。
    • 大卫-我错过了。但是,我不会放弃……反正还没有。检查每个 COALESCE 中有附加值的更新。这对你有帮助吗?
    【解决方案2】:

    我喜欢你的第三个代码块。似乎您的 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 值。两者都将正确匹配。您可以对零件号执行相同操作。

    【讨论】:

    • 我考虑过使用 case 语句,但问题是如果我有 10 个参数并且其中大多数是 Case 语句,SQL 语句会变得非常冗长和混乱。
    • 您可以选择年份和零件编号的幻数(如 -1),然后您无需转换或转换任何内容。这允许您使用第二个代码块。
    【解决方案3】:

    这样试试吧,关键是修复你的空参数值来替代空值,而且由于sql server支持短路评估,所以通常进行空值检查应该会更好。

    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)  
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      相关资源
      最近更新 更多