如果datetime参数为null,则分配一个datetime值

时间:2018-09-11 22:35:42

标签: sql-server tsql reporting-services ssms

我有一个SSRS报告,其中包含开始日期和结束日期参数。对于开始日期和结束日期,可以设置选项NULL。规则是,如果开始日期为空,则检索的数据将从时间开始。如果结束日期为空,则将其设置为今天的日期。这就是我要在这里执行的操作:

SELECT * 
FROM mytab 
WHERE (Start >= CASE @From 
                   WHEN NULL 
                      THEN DATEADD(year, -100, @From)
                END) 
  AND (End <= CASE @To
                 WHEN NULL THEN GETDATE()
              END)

作为测试,我在查询中声明变量@From和@To,将它们设置为NULL并在SSMS上运行它。

我要实现的意思是,如果@From为null,请将值设置为100年前,然后将其与mytab字段“ Start”进行比较。同样,如果@To为null,则将其设置为今天的日期,并与'End'比较。但是,这不会返回任何数据。显然这是错误的,那么正确的方法是什么?

3 个答案:

答案 0 :(得分:1)

这里不需要使用CASE语句,因为我们可以使用ISNULL或COALESCE。

SELECT * 
FROM mytab 
WHERE Start >= ISNULL( @From , DATEADD(year, -100, GETDATE()) ) 
  AND End   <= ISNULL( @To   , GETDATE() )

答案 1 :(得分:0)

CASE语法无法解析所需的NULL。

DECLARE @TEST AS VARCHAR(10)

SET @TEST = NULL

SELECT CASE WHEN @TEST IS NULL THEN 1 ELSE 0 END AS TEST1, 
       CASE @TEST WHEN NULL THEN 1 ELSE 0 END AS TEST2

TEST1的结果为1,TEST2的结果为0,而不是预期的1和1。

SELECT * from mytab WHERE (Start >= CASE WHEN @From IS NULL THEN DATEADD(year, -100, @From) END) 

AND (End <= CASE WHEN @To IS NULL THEN GETDATE() END)

答案 2 :(得分:0)

简单的 case表达式when子句不能匹配null,但是您可以在搜索的中使用is null对其进行测试 casecase when @From is NULL then Cast( '1900-01-01' as Date ) else @From end。请注意,如果else子句都不匹配,则when子句将提供一个值。

针对您的问题的更整洁的解决方案是使用Coalesce

select *
  from MyTab
  where Coalesce( @From, Cast( '1900-01-01' as Date ) ) <= [Start] and
    [End] <= Coalesce( @To, Cast( GetDate() as Date ) );

请注意,将值强制转换为date以消除一天中的时间。