ALL IF SQL中的Null逻辑

时间:2015-06-23 13:47:29

标签: sql sql-server tsql stored-procedures

我们需要在网页中实现搜索功能。所以我们创建了一个存储过程来检索记录。 逻辑是,当我选择输入参数时,Sp返回参数的过滤记录,否则它将检索所有可用记录。

enter image description here

例如:如果我给,

EXEC [WB_GetClassesByLocation_new2] null,null,null,'null',null,NULL,'N','N','N','N','N','N','N',NULL,null,null,null,null,null

(N是Days字段的默认值) SP将返回所有可用记录。  如果我给,

EXEC [WB_GetClassesByLocation_new2] 1000,null,null,'null',null,NULL,'N','N','N','N','N','N','N',NULL,null,null,null,null,null。 SP将返回1000区的记录。我已实现以下逻辑

Select distinct c.classID, co.fCourseName as CourseName, StreetAddress + ', ' + l.City as LocationAddress, s.SessionName, sh.fShift as shift, StartTime, EndTime, c.classname, s.SessionID,
        c.StartDate,c.enddate 
        From dbo.vw_Class c 
        Inner Join dbo.lk_Session s 
        On (s.SessionID = c.sessionID) 
        Inner Join dbo.lk_Course co 
        On (co.CourseID = c.CourseID )
        Inner Join dbo.vw_Location l 
        On (l.locationid = c.locationid) 
        Inner Join lk_District d
        On (d.districtID = c.districtId) 
        Inner Join lk_Province p 
        On (p.provik = d.provik) 
        Inner Join lk_Shift sh 
        On (c.shiftid = sh.shiftid)
       where 
          c.DistrictID       =  case  when @Districtid is null   then c.DistrictID   else  @Districtid  end 
         and c.LocationID    =  case  when @locationid is null   then c.LocationID   else  @locationid  end 
         and s.SessionID     =  case  when @sessionid is null    then s.SessionID    else  @sessionid   end 
         and c.CourseID      =  case  when @levelid  is null     then c.CourseID     else  @levelid     end 
         and c.ShiftID       =  case  when @shiftid   is null    then c.ShiftID      else  @shiftid     end 
         and c.StartDate    >=  case  when @startdate is null    then c.StartDate    else  @startdate   end
         and c.EndDate      <=  case when  @enddate is null      then c.EndDate      else  @enddate     end
         and convert(time,c.StartTime) >= case when @starttime is null then convert(time,c.StartTime) else convert(time,@starttime) end
         and convert(time,c.endtime)   <= case when @endtime is null then convert(time,c.endtime) else convert(time,@endtime) end
         and c.Monday    = case  when @day1 = 'N' then c.monday     else  @day1  end 
         and c.Tuesday   = case  when @day2 = 'N' then c.Tuesday        else  @day2  end 
         and c.Wednesday = case  when @day3 = 'N' then c.Wednesday  else  @day3  end 
         and c.Thursday  = case  when @day4 = 'N' then c.Thursday       else  @day4  end 
         and c.Friday    = case  when @day5 = 'N' then c.Friday     else  @day5  end 
         and c.Saturday  = case  when @day6 = 'N'then c.Saturday        else  @day6  end 
         and c.Sunday    = case  when @day7 = 'N' then c.Sunday     else  @day7  end 
         and c.RowStatus    = 'A' 
         ORDER BY co.fCourseName, s.SessionID ,c.ClassName

但Sp需要花费太多时间来执行。这是在sql server中实现“All IF null”逻辑的正确方法吗?还有其他方法吗?

2 个答案:

答案 0 :(得分:2)

以下是我的表现方式:

( @Districtid is null OR c.DistrictID = @Districtid )
AND
( @Locationid is null OR c.LocationID = @Locationid )
AND
...

但是,当您拥有非常多的这些过滤器,并且您已经接近我要尝试的临界点时,您最好不要创建动态SQL查询。

答案 1 :(得分:2)

如果你有很多过滤器的查询,我知道2个选项:

  1. 使用OR(如上所述),这可能导致查询优化器扫描表。 有关详细信息,请参阅此帖子:How to Optimize the Use of the "OR" Clause When Used with Parameters (SQL Server 2008)

  2. 使用动态SQL - 这可能导致查询优化器计算每个参数中每次更改的执行计划 一个很好的选择是使用Bind Variables的动态sql, 这样,优化器将缓存查询和执行计划。

    declare @sql varchar(500)
    DECLARE @ParmDefinition nvarchar(500);
    
    SET @sql='select * from a where 1=1 '
     if @Locationid  is null
    set @sql=@sql +' and @LocationId is null'
     else
     set @sql=@sql +' and LocationID= @LocationId'
    
      EXECUTE sp_executesql @sql, N'@LocationId int',
                  @LocationID ;