带有WHERE子句逻辑的SQL Server存储过程

时间:2018-03-05 19:27:54

标签: sql sql-server stored-procedures

我的应用程序中有一个结果表和一个允许用户按一个或多个值过滤结果集的框。

我必须在记录中添加可选 needBy日期,以便某人可以指定他们是否需要在特定日期处理请求。

我正在努力的部分是过滤可选的日期结构。我的过滤器如下:

  • 当前=日期需求小于或等于今天的所有请求
  • 未来=所有日期需求大于今天的请求
  • 全部=按日期提供和不提供所有请求

以下是我的查询示例。 WHERE期待@needBy正常工作的SELECT * FROM TABLE WHERE (@requestor IS NULL OR r.Requestor = @requestor) AND (@user IS NULL OR t.QID = @user) AND (@tool IS NULL OR t.ToolID = @tool) AND (@role IS NULL OR t.RoleID = @role) AND (@action IS NULL OR t.ActionID = @action) AND (@status IS NULL OR t.StatusID = @status) AND (@needBy IS NULL OR CASE WHEN @needBy = 'current' THEN r.NeedByDate <= GETUTCDATE() WHEN @needBy = 'future' THEN r.NeedByDate > GETUTCDATE() WHEN @needBy = 'all' THEN r.NeedByDate IS NOT NULL END)

@needBy = 'all'

我应该如何针对日期对此查询进行不同的处理?另一个问题是WHEN/THEN。在这种情况下,我需要所有记录,无论它们在将来有什么日期,过去或提供过。

在上面的代码中,似乎不喜欢SELECT语句中的逻辑运算符。

2 个答案:

答案 0 :(得分:2)

你开始善于OR条件,你只需要一路走下去:

SELECT 
    * 
FROM 
    TABLE
WHERE 
    (@requestor IS NULL OR r.Requestor = @requestor) 
    AND
    (@user IS NULL OR t.QID = @user)
    AND
    (@tool IS NULL OR t.ToolID = @tool)
    AND
    (@role IS NULL OR t.RoleID = @role)
    AND
    (@action IS NULL OR t.ActionID = @action)
    AND
    (@status IS NULL OR t.StatusID = @status)
    AND
    (@needBy IS NULL OR 
         (@needBy = 'current' AND r.NeedByDate <= GETUTCDATE()) OR 
         (@needBy = 'future'  AND r.NeedByDate > GETUTCDATE()) OR 
         (@needBy = 'all' AND r.NeedByDate IS NOT NULL)
     )

请注意,catch-all查询通常会遇到效率低下的执行计划,因为它是基于一组参数编译的,这些参数可能不适合下一组参数。
一种解决方案是将OPTION(RECOMPILE)添加到存储过程。 有关详细信息,请参阅this blog post

答案 1 :(得分:0)

您不需要CASE

 (@needBy IS NULL OR 
   ( @needBy = 'current' AND r.NeedByDate <= GETUTCDATE() )
   OR 
   ( @needBy = 'future' AND r.NeedByDate > GETUTCDATE() )
   OR 
   ( @needBy = 'all' AND r.NeedByDate IS NOT NULL )
                       )