开发者

SQL server SP : sometimes not to be included in WHERE clause

开发者 https://www.devze.com 2022-12-13 16:45 出处:网络
I am very new to SQL Server Stored Procedures, This is My SP : CREATE PROCEDURE [dbo].[spGetBonusRunDetails]

I am very new to SQL Server Stored Procedures, This is My SP :

CREATE PROCEDURE [dbo].[spGetBonusRunDetails]
(
  @StartDate as DATETIME,
  @EndDate as DATETIME,
   @PageNumber int,
  @PageSize int, 
   @Status int
)
AS

;WITH DataCTE AS
(
   SELECT ROW_NUMBER() OVER(Order by Id) as RowNumber
     ,[StartDateTime]
      ,[EndDate]
     ,[Status]
     ,[ExecutionTime]
开发者_运维问答     ,[Code] , TotalRows = Count(*) OVER() 
   FROM [dbo].[BonusRun]
    WHERE ((StartDateTime BETWEEN @StartDate AND @EndDate)  
   OR (EndDate BETWEEN @StartDate AND @EndDate))
   AND (Status = @Status)
 )

I want that @Status condition check sometimes not to be included in WHERE clause.

How to do that ?

Edit :

is it not possible to to write some thing

IF @Status <= 0
 then @Status = NULL 
END IF

and in where statement

AND (Status = @Status OR @Status IS NULL)


AND (Status = ISNULL(@Status, Status))

In this case if @Status is NULL it will be ignored.


A commonly used approach is:

CREATE PROCEDURE [dbo].[spGetBonusRunDetails]
(
  @StartDate as DATETIME,
  @EndDate as DATETIME,
   @PageNumber int,
  @PageSize int, 
   @Status int = NULL
)
AS

;WITH DataCTE AS
(
   SELECT ROW_NUMBER() OVER(Order by Id) as RowNumber
     ,[StartDateTime]
      ,[EndDate]
     ,[Status]
     ,[ExecutionTime]
     ,[Code] , TotalRows = Count(*) OVER() 
   FROM [dbo].[BonusRun]
    WHERE ((StartDateTime BETWEEN @StartDate AND @EndDate)  
   OR (EndDate BETWEEN @StartDate AND @EndDate))
   AND (@Status IS NULL OR Status = @Status)
 )

But please be aware that this can have implications for Parameter Sniffing and the possibility of an inappropriate cached query plan.

In fact, while I always try not to use dynamic TSQL, when there are a large number of optional parameters, it is a valid approach to avoid incorrect cached plans.


The easiest way I've found to do this would be using a case statement. Might not be the most efficient solution, but its better than writing the query twice, once without the where clause (if performance isn't your biggest concern)

   SELECT ROW_NUMBER() OVER(Order by Id) as RowNumber
     ,[StartDateTime]
      ,[EndDate]
     ,[Status]
     ,[ExecutionTime]
     ,[Code] , TotalRows = Count(*) OVER() 
   FROM [dbo].[BonusRun]
    WHERE ((StartDateTime BETWEEN @StartDate AND @EndDate)  
   OR (EndDate BETWEEN @StartDate AND @EndDate))
   AND 
   (CASE WHEN (@Status IS NULL) THEN CAST(1 AS bit) ELSE Status = @Status END);

I think I got that right


How about:

AND (@Status IS NULL OR @Status = Status)

So if @Status is NULL, you would return all types of Status - you could use a default value instead of NULL.

0

精彩评论

暂无评论...
验证码 换一张
取 消