SQL Server中的多个独立IF条件

27

我在存储过程中有多个彼此独立的IF语句。但不知何故,它们被嵌套在一起,好像它们是一个大的if语句的一部分。

ELSE IF(SOMETHNGZ)
 BEGIN
  IF(SOMETHINGY)
   BEGIN..END
  ELSE IF (SOMETHINGY)
   BEGIN..END
  ELSE
   BEGIN..END
  --The above works I then insert this below and these if statement become nested----
  IF(@A!= @SA)

  IF(@S!= @SS)

  IF(@C!= @SC) 

  IF(@W!= @SW)
  --Inserted if statement stop here
 END
ELSE <-- final else    

所以它会被这样处理

IF(@A!= @SA){           
        IF(@S!= @SS){           
            IF(@C!= @SC) {      
                IF(@W!= @SW){}
            }
        }
    }

我希望你能做的是这样

IF(@A!= @SA){}          
IF(@S!= @SS){}      
IF(@C!= @SC){}
IF(@W!= @SW){}

我也尝试过这样做,但出现了“ELSE”附近错误的语法。期望"CONVERSATION"

IF(@A!= @SA)
BEGIN..END                  
IF(@S!= @SS)
BEGIN..END      
IF(@C!= @SC) 
BEGIN..END  
IF(@W!= @SW)
   BEGIN..END
注意,从ELSE <--final else开始到结尾的部分现在嵌套在IF(@W!= @SW)内部。尽管它是外部if语句ELSE IF(SOMETHNGZ)的一部分。 编辑
根据请求,以下是我的完整陈述。
ALTER Procedure [dbo].[SP_PLaces]  
@ID int, 
..more params
AS
BEGIN
SET NOCOUNT ON
DECLARE @SomeId INT
..more varaible
SET @SomeId = user define function()
..more SETS
IF(@ID IS NULL)
BEGIN
BEGIN TRY
    INSERT INTO Places              
    VAlUES(..Values...)            
    ... more stuff...               
    BEGIN TRY       
        exec Store procedure 
            @FIELD = 15, ... more params...             
    END TRY
    BEGIN CATCH
        SELECT ERROR_MESSAGE() AS 'Message' 
        RETURN -1
    END CATCH                      
    RETURN 0                
END TRY
BEGIN CATCH
    SELECT ERROR_MESSAGE() AS 'Message' 
    RETURN -1
END CATCH   
END 
ELSE IF(@ID IS NOT NULL AND @ID in (SELECT ID FROM Places)) 
BEGIN   
     SELECT @MyName = Name ...  
    ...Some stuff....                       
    IF(SOMETHNG_1)          
        BEGIN TRY               
            UPDATE ....                                                                 
        END TRY
        BEGIN CATCH
            SELECT ERROR_MESSAGE() AS 'Message' 
            RETURN -1
        END CATCH
    ELSE IF(SOMETHNG_2)
        BEGIN TRY
            UPDATE ...                                                      
        END TRY
        BEGIN CATCH
            SELECT ERROR_MESSAGE() AS 'Message' 
            RETURN -1
        END CATCH   
    ELSE  
        BEGIN
            BEGIN TRY
                UPDATE ...                                                              
            END TRY
            BEGIN CATCH
                SELECT ERROR_MESSAGE() AS 'Message' 
                RETURN -1
            END CATCH   
        END             
      --The above works I then insert this below and these if statement become nested----
  IF(@A!= @SA)
    BEGIN
     exec Stored procedure 
            @FIELD = 15,
            ... more params...
    END                 
IF(@S!= @SS)
  BEGIN
     exec Stored procedure 
            @FIELD = 10,
            ... more params...
    END     
IF(@C!= @SC) 
  BEGIN
     exec Stored procedure 
            @FIELD = 17,
            ... more params...
    END 
IF(@W!= @SW)
    BEGIN
     exec Stored procedure 
            @FIELD = 12,
            ... more params...
    END
  --Inserted if statement stop here             
END     
ELSE    
    BEGIN
        SET @ResultMessage = 'Update/Delete Failed. No record found with   ID:'+CONVERT(varchar(50), @ID) 
        SELECT @ResultMessage AS 'Message' 
        RETURN -1
    END
Set NOCOUNT OFF
END

3
附注:你不应该为你的存储过程使用 sp_ 前缀。微软已经将该前缀保留给自己使用(请参阅命名存储过程,而且你可能会在未来某个时候遇到名称冲突的风险。这也会影响你的存储过程性能。最好是避免使用 sp_,使用其他前缀或完全不使用前缀! - marc_s
3个回答

44

如果您想将一个变量与多个条件进行比较,那么可以使用类似以下的代码块: 在这里,条件为真的代码块将被执行,其他代码块将被忽略。

IF(@Var1 Condition1)
     BEGIN
      /*Your Code Goes here*/
     END

ELSE IF(@Var1 Condition2)
      BEGIN
        /*Your Code Goes here*/ 
      END 

    ELSE      --<--- Default Task if none of the above is true
     BEGIN
       /*Your Code Goes here*/
     END

如果您需要根据多个变量检查条件,则必须使用多个 IF 语句,每个代码块将独立于其他代码块执行。

IF(@Var1 Condition1)
 BEGIN
   /*Your Code Goes here*/
 END


IF(@Var2 Condition1)
 BEGIN
   /*Your Code Goes here*/
 END


IF(@Var3 Condition1)
 BEGIN
   /*Your Code Goes here*/
 END

每个IF语句后面,如果有多个语句需要执行,你必须将它们放在BEGIN..END块中。无论如何,使用BEGIN..END块始终是最佳实践。

更新

在你的代码中发现了一些缺失的BEGIN END块。

ELSE IF(@ID IS NOT NULL AND @ID in (SELECT ID FROM Places))   -- Outer Most Block ELSE IF
BEGIN   
     SELECT @MyName = Name ...  
    ...Some stuff....                       
    IF(SOMETHNG_1)         -- IF
                 --BEGIN
        BEGIN TRY               
            UPDATE ....                                                                 
        END TRY

        BEGIN CATCH
            SELECT ERROR_MESSAGE() AS 'Message' 
            RETURN -1
        END CATCH
                -- END
    ELSE IF(SOMETHNG_2)    -- ELSE IF
                 -- BEGIN
        BEGIN TRY
            UPDATE ...                                                      
        END TRY
        BEGIN CATCH
            SELECT ERROR_MESSAGE() AS 'Message' 
            RETURN -1
        END CATCH   
               -- END
    ELSE                  -- ELSE
        BEGIN
            BEGIN TRY
                UPDATE ...                                                              
            END TRY
            BEGIN CATCH
                SELECT ERROR_MESSAGE() AS 'Message' 
                RETURN -1
            END CATCH   
         END             
      --The above works I then insert this below and these if statement become nested----
          IF(@A!= @SA)
            BEGIN
             exec Store procedure 
                    @FIELD = 15,
                    ... more params...
            END                 
        IF(@S!= @SS)
          BEGIN
             exec Store procedure 
                    @FIELD = 10,
                    ... more params...

如所述,我已经在使用BEGIN..END,但实际上使用它会抛出一个错误。 - Jack Thor
@JackThor 使用 BEGIN..END 抛出错误??不可能是这个,肯定是其他东西抛出的错误。为了调试它,我会将所有的代码都拿掉,在每个 BEGIN END 块中使用 PRINT 语句,比如 PRINT 'Block 1' 等等,以检查你的代码控制跳进跳出的块之间的情况。 - M.Ali
使用 Begin..END 为我插入的 If 语句组中的最后一个 End 给它一个红色的波浪线。当我将鼠标悬停在上面时,它会显示“附近有语法错误。期望“CONVERSATION”。 - Jack Thor
1
@JackThor 看看我的更新,你在最外层的ELSE IF块中缺少了一些BEGIN END块,我已经在以两个--开头的注释中添加了它们,忽略注释的ELSE和IF ELSE :) - M.Ali

2
为了避免语法错误,请确保在IF子句后始终加上BEGINEND,例如:
IF (@A!= @SA)
   BEGIN
   --do stuff
   END
IF (@C!= @SC)
   BEGIN
   --do stuff
   END

...等等。这应该像预期的那样工作。将BEGINEND关键字想象为相应的开括号和闭括号。


我检查了我上次发布的代码块,它会抛出一个错误。 - Jack Thor
请发布完整的语句。错误在其他地方。 - LittleSweetSeas

1
也许这有点冗余,但似乎没有人提到这个解决方案。
作为一个SQL的初学者,我发现在使用BEGINEND时,SSMS通常会在END处添加一个带有incorrect syntax near 'END'的波浪线,仅因为它们之间还没有内容。如果你只是设置BEGINEND以开始并稍后添加实际查询,则只需添加一个虚假的PRINT语句,这样SSMS就不会再打扰你了。
例如:
IF (1=1)
BEGIN
  PRINT 'BOGUS'
END

以下内容确实会让你走上错误的道路,让你认为自己犯了语法错误,但实际上这只是意味着你仍然需要在BEGIN和END之间添加内容。
IF (1=1)
BEGIN
END

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接