SQL“IF”,“BEGIN”,“END”,“END IF”?

时间:2008-12-31 21:07:33

标签: sql

根本不是SQL人员。请顾问写下以下代码。

首先,它确保只选择了一所小学 - 然后,在BEGIN之后,如果变量@Term等于3,我们想在IF语句下做这些东西。这是问题所在。当@Term不是= 3时,我们仍然想要下拉并执行SECOND INSERT INTO @Classes部分。仅供参考 - 当运行时,术语为= 3,但它不同时执行INSERT - 如果在“IF @Term = 3”部分的末尾有一个END IF,而不仅仅是一个简单的END?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school...

BEGIN

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part

    IF @Term = 3

    BEGIN

        INSERT INTO @Classes

        SELECT      
        XXXXXX  
        FROM XXXX blah blah blah

    END   <----(Should this be ENDIF?)

---- **always** "fall thru" to here, no matter what @Term is equal to - always do the following INSERT for all elementary schools

    INSERT INTO @Classes    
    SELECT
    XXXXXXXX    
    FROM XXXXXX (more code) 

END

10 个答案:

答案 0 :(得分:43)

它与SQL语言的Normal Form有关。根据定义,IF语句只能采用单个 SQL语句。但是,有一种特殊的SQL语句可以包含多个SQL语句BEGIN-END块。

如果省略BEGIN-END块,则SQL将运行正常,但它只会执行IF中的第一个语句。

基本上,这个:

IF @Term = 3
    INSERT INTO @Classes
    SELECT              
        XXXXXX  
    FROM XXXX blah blah blah

BEGIN-END块相同,因为您只执行单个语句。但是,出于同样的原因,在类似C语言的IF语句中不包括大括号是个坏主意,使用BEGIN 总是更好和END

答案 1 :(得分:23)

SQL中没有ENDIF。

如果if表达式为真,则直接跟随IF的语句才会执行。

BEGIN ... END构造与IF分开。它将多个语句绑定在一起作为一个块,可以将它们视为单个语句。因此BEGIN ... END可以在IF之后直接使用,因此BEGIN .... END序列中的整个代码块将被执行或跳过。

在您的情况下,我怀疑FROM XXXXX之后的“(更多代码)”是您的问题所在。

答案 2 :(得分:9)

关闭代码看起来正确。如果你尝试使用'Else'并看看会发生什么怎么办?

IF @SchoolCategoryCode = 'Elem' 

--- We now have determined we are processing an elementary school...

BEGIN

---- Only do the following if the variable @Term equals a 3 - if it does not, skip just this first part

    IF @Term = 3
    BEGIN
        INSERT INTO @Classes

        SELECT              
            XXXXXX  
        FROM XXXX blah blah blah

        INSERT INTO @Classes    
        SELECT
        XXXXXXXX    
        FROM XXXXXX (more code) 
    END   <----(Should this be ENDIF?)
    ELSE
    BEGIN


        INSERT INTO @Classes    
        SELECT
        XXXXXXXX    
        FROM XXXXXX (more code) 
    END
END

答案 3 :(得分:3)

如果这是MS Sql Server那么你所拥有的应该可以正常工作...... 事实上,从技术上讲,你不需要Begin&amp; amp;结束,在开始 - 结束块中只有一个语句...(我假设@Classes是一个表变量?)

If @Term = 3
   INSERT INTO @Classes
    SELECT                  XXXXXX  
     FROM XXXX blah blah blah
-- -----------------------------

 -- This next should always run, if the first code did not throw an exception... 
 INSERT INTO @Classes    
 SELECT XXXXXXXX        
 FROM XXXXXX (more code)

答案 4 :(得分:2)

您还可以重写代码以完全删除嵌套的“If”语句。

INSERT INTO @Classes    
SELECT XXXXXX      
FROM XXXX 
Where @Term = 3   

---- **always** "fall thru" to here, no matter what @Term is equal to - always do
---- the following INSERT for all elementary schools    
INSERT INTO @Classes        
SELECT    XXXXXXXX        
FROM XXXXXX (more code) 

答案 5 :(得分:1)

如果我没记错的话,我经常会这样做......在Transact-Sql中没有END IF支持。 BEGIN和END应该完成这项工作。你收到错误了吗?

答案 6 :(得分:1)

第二次插入@clases失败的唯一时间是第一个插入语句中发生错误。

如果是这种情况,那么你需要决定第二个语句是否应该在第一个OR之前运行,如果你需要一个事务来执行回滚。

答案 7 :(得分:0)

根据您对要执行的操作的描述,代码似乎是正确的。 ENDIF不是有效的SQL循环控制关键字。你确定INSERTS实际上是在拉数据放入@Classes吗?事实上,如果它很糟糕,它就不会运行。

您可能想要尝试的是在其中放置一些PRINT语句。在每个INSERTS上面放一个PRINT,只输出一些愚蠢的文本,以显示该行正在执行。如果你得到两个输出,那么你的SELECT ... INSERT ...是可疑的。您也可以只使用SELECT代替PRINT(即没有INSERT),并确切地查看正在拉取的数据。

答案 8 :(得分:0)

Blockquote

就像.NET中的括号一样看

IF
  BEGIN
      do something
  END
ELSE 
  BEGIN 
      do something
  ELSE

等于

if
{
   do something
}
else
{
   do something
}

答案 9 :(得分:-12)

坦率地说,这似乎应该在应用程序层,而不是数据库层......