简体   繁体   English

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

[英]SQL Server stored procedure with WHERE clause logic

I have a table of results in my application and a box that allows a user to filter the result set by one or more values. 我的应用程序中有一个结果表,还有一个框,允许用户按一个或多个值过滤结果集。

I had to add an optional needBy date to the records so that a person could specify if they need the request to be handled by a certain date. 我必须在记录中添加一个可选的 needBy日期,以便一个人可以指定他们是否需要在某个日期之前处理请求。

The part I am struggling with is the filtering of the optional date structure. 我正在努力的部分是可选日期结构的过滤。 My filters are as follows: 我的过滤器如下:

  • Current = All requests that have a need by date less than or equal to today 当前=所有需要的日期小于或等于今天的请求
  • Future = All requests with a need by date that is greater than today 将来=所有需要的日期大于今天的请求
  • All = All requests both with and without a need by date 全部=按日期需要和不需要的所有请求

Here is an example of my query. 这是我的查询示例。 The WHERE for everything expect the @needBy is working just fine. 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)

How should I approach this query differently for the dates? 我应该如何以不同的方式处理日期查询? The one additional problem is @needBy = 'all' . 另一个问题是@needBy = 'all' In this situation, I need all records, regardless of it having a date in the future, in the past, or provided at all. 在这种情况下,我需要所有记录,无论它有将来,过去或提供的日期。

In my code above, it seems to not like the logic operators that are inside of the WHEN/THEN statement. 在上面的代码中,似乎不喜欢WHEN/THEN语句中的逻辑运算符。

You started good with the OR conditions, you just need to go all the way: 您从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)
     )

Please note that catch-all queries often suffer from inefficient execution plan, since it's compiled based on a set of parameters that might not be the best for the next set of parameters. 请注意,由于所有查询都是基于一组参数(可能不是最适合下一组参数的最佳参数)进行编译的,因此其执行计划通常效率不高。
One solution for that would be to add OPTION(RECOMPILE) to the stored procedure. 一种解决方案是将OPTION(RECOMPILE)添加到存储过程。 For more information, Please refer to this blog post 有关更多信息,请参阅此博客文章

You don't need CASE : 您不需要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 )
                       )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM