SQL Server:IF条件在存储过程中不起作用

时间:2016-04-11 20:26:29

标签: sql sql-server stored-procedures

我的存储过程中有这个条件来确定使用哪个WHERE子句:

IF (@communityDesc = 'All Areas')
BEGIN
    WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (SELECT name 
                                               FROM dbo.splitstring(@communityDesc)) 
      AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
END
ELSE
BEGIN
    WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
END
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END

但是我得到了很多错误:

  

Msg 156,Level 15,State 1,Procedure GetProductionSchedule,Line 256
  关键字'WHERE'附近的语法不正确。

     

Msg 156,Level 15,State 1,Procedure GetProductionSchedule,Line 256
  关键字“AND”附近的语法不正确。

我做错了什么?

3 个答案:

答案 0 :(得分:3)

您无法通过条件分离查询。你必须做类似的事情。

if(@communityDesc = 'All Areas')
BEGIN

    SELECT * FROM Table  
    WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN 
    (select name from dbo.splitstring(@communityDesc)) 
    AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
    ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
END
else
BEGIN
    SELECT * FROM Table  
    WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
    ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END
END

您的另一个选择是有条件地构建查询:

DECLARE @Query VARCHAR(1000)

SET @Query = 'SELECT * FROM TABLE ' 

 if(@communityDesc = 'All Areas')
 BEGIN
     SET @Query = @Query + 
     'WHERE V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (select name from dbo.splitstring(@communityDesc)) AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() '
 END
 ELSE

     SET @Query = @Query + 
    'WHERE V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() '
 BEGIN
     SET @Query = @Query + 'ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END'
 END

exec sp_executesql @Query

答案 1 :(得分:1)

或者只是将所有逻辑放入单个WHERE

SELECT  *
FROM    [Table]
WHERE   V_CONSTAT_ACTUAL_DATES.DATE_TO_END >= GETDATE()
        AND (@communityDesc = 'All Areas'
             OR V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (SELECT  name
                                                    FROM    dbo.splitstring(@communityDesc)))

我不确定你的逻辑是否正确..你可能想要拆分@communityDesc,如果它不等于All Areas我已经更新了我的答案以反映我的意思。

答案 2 :(得分:1)

您应该像这样写

-- your preceding select statements followed by this line
SELECT * FROM V_CONSTAT_ACTUAL_DATES
WHERE 
(
 @communityDesc = 'All Areas' AND 
 V_CONSTAT_ACTUAL_DATES.AREA_DESC IN (select name from dbo.splitstring(@communityDesc)) AND 
V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
)
OR
( @communityDesc <> 'All Areas' AND V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE()
)
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END

这也可以简化为

-- your preceding select statements followed by this line
SELECT * FROM V_CONSTAT_ACTUAL_DATES
WHERE 
  V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() 
 AND NOT
  (
 @communityDesc <> 'All Areas' OR
 V_CONSTAT_ACTUAL_DATES.AREA_DESC not IN (select name from dbo.splitstring(@communityDesc)) 
)
ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END

可以进一步优化,如下所示

    -- your preceding select statements followed by this line
   SELECT * FROM V_CONSTAT_ACTUAL_DATES
   LEFT JOIN (select name from dbo.splitstring(@communityDesc) Temp
     ON Temp.name=V_CONSTAT_ACTUAL_DATES.AREA_DESC 
    WHERE 
      V_CONSTAT_ACTUAL_DATES.DATE_TO_END>=GETDATE() 
     AND NOT
      (
     @communityDesc <> 'All Areas' OR  Temp.Name is null
      ) 
    )
    ORDER BY V_CONSTAT_ACTUAL_DATES.DATE_TO_END