SQL存储过程中的日期明智可选参数搜索

时间:2015-06-29 09:35:25

标签: sql sql-server stored-procedures

我想在搜索时从我的请假申请表中提取休假报告。在表中,我有Leavefrom(datetime),LeaveTo(datetime)列。现在我想根据这两列来获取行。我的搜索参数可以为空 @employeeid,@ datefrom,@ dateto。

我需要在Leavefrom,LeaveTo的日期之间得到结果。 我正在尝试为此创建一个存储过程。

ALTER PROCEDURE [dbo].[SP_GetSpecificLeaveReport]
@empid int=null,
@leavefrom date=null,
@leaveto date=null
AS
BEGIN
    SET NOCOUNT ON;
    SELECT ela.appliedDate,ela.appliedBy,ela.leaveFrom,ela.leaveTo,ela.noOfDays,
    ejd.firstName,ejd.lastName,
    ltm.leaveType
    from dbo.tblEmployeeLeaveApplication as ela inner join dbo.tblEmployeeJobDetails as
    ejd on ela.empId=ejd.recordId inner join dbo.tblLeaveTypeMaster as ltm 
    on ela.leaveTypeId=ltm.record_Id where



END

3 个答案:

答案 0 :(得分:0)

尝试此查询添加

where ela.empId=IFNULL(ela.empId,ela.empId)
and ltm.leavedatefrom>=IFNULL(@leavefrom,ltm.leavedatefrom)
and ltm.leavedateto<=IFNULL(@leaveto,ltm.leavedateto)

答案 1 :(得分:0)

这种查询称为catch-all查询 有多种方法可以执行此操作,使用iif中的where (@empid is null or ela.empId = @empid) and (@leavefrom is null or ( ltm.leavedatefrom >= @leavefrom and ltm.leavedatefrom < dateadd(day, 1, @leavefrom) ) and (@leaveto is null or ( ltm.leavedateto >= @leaveto and ltm.leavedateto < dateadd(day, 1, @leaveto)) 就是其中之一,但只能在sql server 2012或更高版本上运行。 我建议使用一个更长的where子句来获得更好的性能和兼容性(这应该适用于任何版本,甚至是sql server 7):

datetime

注意:由于您的数据库列的类型为date,但您的参数类型为>=...or,因此我有date条件来捕获所有日期时间与特定日期匹配的值 此外,您可能需要从datetime投射到tags

此外,您应该知道,使用全部搜索查询可能会因查询计划兑现而导致性能下降。
如果遇到性能问题,可能需要在查询中添加重新编译提示,以便每次执行存储过程时都可以获得最佳查询计划。阅读Mukesh's answer了解更多详情。

答案 2 :(得分:0)

尝试以下,

ALTER PROCEDURE [dbo].[SP_GetSpecificLeaveReport]
        @empid int=null,
        @leavefrom date=null,
        @leaveto date=null
    AS
    BEGIN
        SET NOCOUNT ON;
            SELECT 
                ela.appliedDate,ela.appliedBy,ela.leaveFrom,ela.leaveTo,ela.noOfDays,
                ejd.firstName,ejd.lastName,
                ltm.leaveType
            from dbo.tblEmployeeLeaveApplication as ela 
                inner join dbo.tblEmployeeJobDetails as ejd on ela.empId=ejd.recordId 
                inner join dbo.tblLeaveTypeMaster as ltm on ela.leaveTypeId=ltm.record_Id 
            where
            1 = case when Isnull(@empid,0) == 0 then 
                    case when ela.empId == @empid then 1 else 0 end
                else 0 end
            And case when isnull(@leavefrom,'1900-01-01') == '1900-01-01' then 
                    case when ela.leaveFrom >= @leavefrom then 1 else 0 end
                else 0 end
            And case when isnull(@leavefrom,'1900-01-01') == '1900-01-01' then 
                    case when ela.leaveto <= @leaveto then 1 else 0 end
                else 0 end


    END