存储过程 SQL Server 中 IF ELSE 的替代方案

Vbp*_*Vbp 3 sql sql-server stored-procedures

我是存储过程的新手并且仍在学习,下面是我尝试过的并且也在工作。但是,我只有一个更改,ad.Indicator并且我在IF, ELSE IF.

有一个更好的方法吗?(我正在使用 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
Run Code Online (Sandbox Code Playgroud)

Mit*_*eat 6

执行此操作的一种方法(尽管它可能会导致更糟糕的查询计划):

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
Run Code Online (Sandbox Code Playgroud)

[这是否会产生更好或更坏的计划还有待观察......]

此外,请注意:

  • 不推荐使用 SELECT *。使用明确的列列表

  • 包含字符串值“真”和“假”的列作为位列会更好

  • 如果您的日期有时间部分,请小心。如果他们这样做了,有几种方法可以解决这个问题,也许最直接的方法是转换为 Date 数据类型(SQL Server 2008 及更高版本):

    WHERE CAST(fd.SG as Date) BETWEEN @startdate AND @enddate 
    
    Run Code Online (Sandbox Code Playgroud)

但请注意,这可能会使适当索引的使用无效。(还假定@startDate@enddate不具有时间部分)