其中条件基于参数值

时间:2014-10-28 18:25:31

标签: sql sql-server tsql

我有以下程序:

CREATE PROCEDURE LoadSoldItens  
        @DateStart DATETIME,  
        @DateEnd DATETIME,
        @SectionId INT = NULL
AS                  
BEGIN                  
    SELECT SectionId, Name INTO #Sections  
        FROM LoadSections(@SectionId)    

    SELECT S.Id AS SoldId,   
           S.Quantity AS SoldQuantity,   
      FROM SoldItens S WITH(NOLOCK)  
        LEFT JOIN #Sections SC ON S.SectionId = SC.SectionId
     WHERE (ISNULL(S.SoldDate, @DateStart) BETWEEN @DateStart AND @DateEnd)  
     -- AND --Here i'm stuck ....
END  

参数@SectionId是可选的,如果用户为@SectionId参数发送NULL或-10,那么我需要检索具有S.SectionId null值或任何值的所有数据。

如果用户发送@SectionId> 0,然后我需要检索具有S.Section = @SectionId的数据。

我的最后一次尝试是:

AND (ISNULL(@SectionId, S.SectionId) IS NULL 
            OR ISNULL(@SectionId, S.SectionId) IS NOT NULL)
-- How to check @SectionId = -10 or @SectionId > 0

有人可以帮我一把吗?

提前感谢。

2 个答案:

答案 0 :(得分:3)

就像这样......如果不是null,则与section id比较,如果为null,则与自身进行比较。

AND ISNULL(@SectionId, S.SectionId) = S.SectionID

检查-10执行此操作:

WHERE (...
   AND ISNULL(@SectionId, S.SectionId) = S.SectionID)
   OR @SectionID = -10 

请运行以下完整查询,它将起作用:

SELECT S.Id AS SoldId,   
       S.Quantity AS SoldQuantity,   
FROM SoldItens S WITH(NOLOCK)  
LEFT JOIN #Sections SC ON SC.SectionId = SC.SectionId
WHERE ISNULL(S.SoldDate, @DateStart) BETWEEN @DateStart AND @DateEnd  
  AND (
     ISNULL(@SectionId, S.SectionId) = S.SectionID)
     OR @SectionID = -10 
  )

答案 1 :(得分:1)

虽然你可以这样做,但你可能不应该这样做。优化器需要先检查绑定变量,然后才能制定正确的执行计划。

更好的方法是在TSQL中执行逻辑,这将使优化器清楚地理解所需的结果集。还要考虑重写

(ISNULL(S.SoldDate,@ DateStart)BETWEEN @DateStart和@DateEnd)

(@DateStart与@DateEnd或S.SoldDate之间的S.SoldDate为空)

CREATE PROCEDURE LoadSoldItens  
        @DateStart DATETIME,  
        @DateEnd DATETIME,
        @SectionId INT = NULL
AS                  
BEGIN                  
    SELECT SectionId, Name INTO #Sections  
        FROM LoadSections(@SectionId)   

    if  @SectionId is null or @SectionId = -10
    begin
        SELECT S.Id AS SoldId,   
               S.Quantity AS SoldQuantity,   
          FROM SoldItens S WITH(NOLOCK)  
            LEFT JOIN #Sections SC ON SC.SectionId = SC.SectionId
         WHERE (S.SoldDate BETWEEN @DateStart AND @DateEnd  or S.SoldDate is NULL)
    end
    else
    begin

        SELECT S.Id AS SoldId,   
               S.Quantity AS SoldQuantity,   
          FROM SoldItens S WITH(NOLOCK)  
            LEFT JOIN #Sections SC ON SC.SectionId = SC.SectionId
         WHERE (S.SoldDate BETWEEN @DateStart AND @DateEnd  or S.SoldDate is NULL)
         and s.SectionID = @SectionId
    end
END