SQL“如果”、“开始”、“结束”、“结束如果”?

SQL“如果”、“开始”、“结束”、“结束如果”?,sql,Sql,一点也不喜欢SQL。让顾问编写以下代码 首先,它确保只选择了一所小学——然后,在开始之后,如果变量@Term等于a3,我们想在if语句下做一些事情。问题出在这里。当@Term不等于3时,我们仍然希望下拉并在@Classes部分中进行第二次插入。仅供参考-运行时,术语为=3,但它不会同时执行插入操作-IF@Term=3节的末尾是否应该有一个结束IF,而不仅仅是一个简单的结束IF IF @SchoolCategoryCode = 'Elem' --- We now have determined

一点也不喜欢SQL。让顾问编写以下代码

首先,它确保只选择了一所小学——然后,在开始之后,如果变量@Term等于a3,我们想在if语句下做一些事情。问题出在这里。当@Term不等于3时,我们仍然希望下拉并在@Classes部分中进行第二次插入。仅供参考-运行时,术语为=3,但它不会同时执行插入操作-IF@Term=3节的末尾是否应该有一个结束IF,而不仅仅是一个简单的结束IF

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

如果这是MS Sql Server,那么您拥有的应该可以正常工作。。。 事实上,从技术上讲,你不需要;根本不需要Begin和End,因为Begin End块中只有一条语句。。。我假设@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)

如果我没记错的话,而且更多的时候我没有记错。。。Transact-Sql中没有Endif支持。开始和结束应该完成这项工作。是否有错误?

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


您可能想要尝试的是在其中放入一些打印语句。在每一个插入的上面放一个打印,只是输出一些愚蠢的文本,以显示该行正在执行。如果您同时获得两个输出,则选择…插入。。。这是可疑的。您也可以只执行SELECT代替打印,即不执行INSERT,并准确查看正在提取的数据。

SQL中没有ENDIF

仅当IF表达式为true时,才会执行直接跟随IF的语句

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


在您的情况下,我怀疑XXXXX后面的更多代码就是您的问题所在。

这与SQL语言的正常形式有关。根据定义,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。

代码看起来很正确。如果你试着用“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

第二次插入@clases失败的唯一原因是第一次插入语句中出现错误


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

您还可以重写代码以完全删除嵌套的“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) 
大宗报价

只需像.NET中的括号一样看待它

IF
  BEGIN
      do something
  END
ELSE 
  BEGIN 
      do something
  ELSE
等于

if
{
   do something
}
else
{
   do something
}

又是我。我不能再加一个了。因为,无论@Term=3思维是否良好,我总是想做第二个INSERT语句。下一个逻辑步骤是使用UNION ALL select将其简化为一个insert。我将代码缩进最内部的Begin End块,认为这可能会有所帮助。非常有用。