如何在SQL存储过程中检查两个日期是否在特定日期范围内?

时间:2017-06-02 16:21:52

标签: sql sql-server stored-procedures

这是我的存储过程:

ALTER Procedure [dbo].[SearchCreatedAssignments]
(@LessonName NVarchar(MAX), @DateFrom date, @DateTo Date, @LocationCode NVarchar(MAX))
As 
BEGIN 
Select *
from dbo.CreatedAssignments
--IsNull replaces NULL with the specified replacement value.
--IsNull(check_expression, replacement_value)
--NullIf returns a null value if the two specified expressions are equal.
--In other words, NULLIF returns the first expression if the two expressions are not equal. 
--If the expressions are equal, NULLIF returns a null value of the type of the first expression. 

where LessonName   = IsNull(NullIf(@LessonName,''),LessonName) 
 AND  StartDate    = IsNull(NullIf(@DateFrom,''),StartDate) 
 AND  EndDate      = IsNull(NullIf(@DateTo,''),EndDate)
 AND  LocationCode = IsNull(NullIf(@LocationCode,''),LocationCode)
 AND status ='a'

END

如您所见,此存储过程已设置,以便用户可以搜索任何一个搜索条件或搜索条件的任意组合(条件是列名称),同时将其他条件留空。例如,假设用户想要仅lessonname搜索数据库。此存储过程允许用户执行此操作。它将返回与指定的lessonname匹配的所有结果,而不管其他条件是否为空。所以,这是我的问题:如何保留此逻辑,但返回startdateenddate落在特定日期范围内的结果?我知道我需要使用between关键字,但我不确定如何在保留逻辑的同时实现此更改。任何帮助是极大的赞赏。

2 个答案:

答案 0 :(得分:1)

如果您希望开始日期和结束日期在相同的日期范围内 - 即您的@DateFrom和@DateTo参数 - 您可以这样做:

ALTER Procedure [dbo].[SearchCreatedAssignments]
(@LessonName NVarchar(MAX), @DateFrom date, @DateTo Date, @LocationCode 
NVarchar(MAX))
As 
BEGIN 
Select *
from dbo.CreatedAssignments
--IsNull replaces NULL with the specified replacement value.
--IsNull(check_expression, replacement_value)
--NullIf returns a null value if the two specified expressions are equal.
--In other words, NULLIF returns the first expression if the two expressions     are not equal. 
--If the expressions are equal, NULLIF returns a null value of the type of     the first expression. 

where LessonName   = IsNull(NullIf(@LessonName,''),LessonName) 
 AND  StartDate    BETWEEN IsNull(NullIf(@DateFrom,''),'1901-01-01') AND IsNull(NullIf(@DateTo,''),'2199-01-01')
 AND  EndDate      BETWEEN IsNull(NullIf(@DateFrom,''),'1901-01-01') AND IsNull(NullIf(@DateTo,''),'2199-01-01')
 AND  LocationCode = IsNull(NullIf(@LocationCode,''),LocationCode)
 AND status ='a'

END

请注意,我更改了IsNulls的第二个参数,以使用标量值而不是实际列。我这样做是为了防止一个日期参数留空时出现问题,这可能会使您的比较日期错误(例如StartDate BETWEEN 1/1/2017和2015年1月1日)。

答案 1 :(得分:0)

您可以在每个字段上使用运算符。

ALTER Procedure [dbo].[SearchCreatedAssignments]
(@LessonName NVarchar(MAX), @DateFrom date, @DateTo Date, @LocationCode NVarchar(MAX))
As 
BEGIN 
Select *
from dbo.CreatedAssignments
--IsNull replaces NULL with the specified replacement value.
--IsNull(check_expression, replacement_value)
--NullIf returns a null value if the two specified expressions are equal.
--In other words, NULLIF returns the first expression if the two expressions are not equal. 
--If the expressions are equal, NULLIF returns a null value of the type of the first expression. 

where LessonName   = IsNull(NullIf(@LessonName,''),LessonName) 
 AND  (StartDate BETWEEN  @DateFrom AND @DateTo) AND 
 AND  (EndDate BETWEEN  @DateFrom AND @DateTo) AND
 AND  LocationCode = IsNull(NullIf(@LocationCode,''),LocationCode)
 AND status ='a'

END