2013-12-06 6 views
1

Я новичок в хранимых процедурах и все еще изучаю, ниже я также старался и работает. Но у меня есть только одно изменение на ad.Indicator, и я пишу один и тот же запрос трижды в IF, ELSE IF.Альтернативы IF ELSE в хранимой процедуре SQL Server

Не может ли это быть сделано лучше? (Я использую SQL Server)

ALTER PROCEDURE TestingSP 
    @startdate Datetime, 
    @enddate Datetime, 
    @source Varchar(10) 
AS 
BEGIN 
    IF(@source = 'None') 
     SELECT * 
     FROM FD.T fd 
     INNER JOIN AD.T ad ON fd.OCD = ad.ACD 
     WHERE fd.SG BETWEEN @startdate AND @enddate 

    ELSE IF(@source = 'Air') 
     SELECT * 
     FROM FD.T fd 
     INNER JOIN AD.T ad ON fd.OCD = ad.ACD 
     WHERE fd.SG BETWEEN @startdate AND @enddate AND ad.Indicator = 'True' 

    ELSE IF(@source = 'Not Air') 
     SELECT * 
     FROM FD.T fd 
     INNER JOIN AD.T ad ON fd.OCD = ad.ACD 
     WHERE fd.SG BETWEEN @startdate AND @enddate AND ad.Indicator = 'False' 
END 

ответ

4

Один из способов сделать это (хотя это могло бы, возможно, приведет к худшему плану запроса):

Select * 
FROM FD.T fd 
INNER JOIN AD.T ad on fd.OCD = ad.ACD 
WHERE fd.SG BETWEEN @startdate AND @enddate 
     AND ad.Indicator = CASE 
           WHEN @source = 'Not Air' THEN 'False' 
           WHEN @source = 'Air' THEN 'True' 
           ELSE ad.Indicator 
         END 

[Независимо от того, что порождает лучше или хуже план остается видно ...]

Кроме того, обратите внимание:

  • Использование SELECT * не рекомендуется. Использование явного списка столбцов

  • столбец, содержащий строковые значения «True» и «Ложь» было бы лучше, как битовая колонке

  • Будьте осторожны, если ваши даты имеют временную часть. Если они есть несколько способов справиться с этим, пожалуй, самым простым способом является приведение к дате типа данных (SQL Server 2008 года):

    WHERE CAST(fd.SG as Date) BETWEEN @startdate AND @enddate 
    

Но следует помнить, что это может привести к аннулированию использования соответствующего индекса. (Также предполагает, что @startDate и @enddate не имеют временной части)

+0

+1 У них есть временная часть. Не могли бы вы предложить, что можно сделать, чтобы справиться с этим? – Vbp

+0

Я считаю, что это пропустит условие «Нет». Возможно, CASE WHEN @source = 'Not Air' THEN 'False' WHEN 'None' THEN ad.Indicator ELSE 'True' END – dazedandconfused

+0

Вы правы: я пропустил это (или был отредактирован?). Я обновлю. Спасибо –

Смежные вопросы