2014-10-28 6 views
0

У меня следующая процедура:Там, где условие основано на значении параметра

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 параметра является необязательным и, если пользователь посылает значение NULL или -10 для параметра @SectionId, то мне нужно, чтобы получить все данные, имеют значение 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 

Любой желающий мог дать мне руку, пожалуйста?

Благодарим заранее.

ответ

3

Просто как это ... по сравнению с идентификатором раздела, если не null или к нему, если 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 
) 
+0

Если я это сделаю, я верну только строки, которые S.SectionId не являются нулевыми, а если @SectionId равно null, мне нужно получить строки с любыми значениями в S.SectionId (включая нулевые значения) – placplacboom

+2

@placplacboom - это это то, что он делает, если @ SectionId равно null, он соответствует всем. – Hogan

+0

И -10 происходит от «exec LoadSoldItens »01/01/2013 ', '12/31/2014', -10 ' – placplacboom

1

Хотя вы можете сделать это, вероятно, не следует. Оптимизатор должен будет просмотреть ваши переменные связывания, прежде чем он сможет сформулировать правильный план выполнения.

Лучшим способом справиться с этим было бы просто выполнить логику в TSQL, которая даст оптимизатору четкое представление о желаемом наборе результатов. Также рассмотрим перезапись

(ISNULL (S.SoldDate, @DateStart) МЕЖДУ @DateStart И @DateEnd)

быть (S.SoldDate МЕЖДУ @DateStart И @DateEnd или S.SoldDate является Null)

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 
+0

Не могу ли я это сделать, используя больше условий на том месте где? – placplacboom

+1

Да, ответ Хогана показывает, как добавить его в предложение where. – Will