/ / SQL “IF”, “BEGIN”, “END”, “END IF”? - sql

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

Não é uma pessoa do SQL. Tenha o seguinte código que um consultor escreveu.

Primeiro, garante que apenas uma escola primáriafoi escolhido - então, após o BEGIN, se a variável @Term for igual a 3, queremos fazer o material sob essa instrução IF. Aqui está o problema. Quando @Term não é = 3 nós ainda queremos drop down e fazer a parte de SECOND INSERT INTO @Classes FYI - o Termo é = 3 quando isso está sendo executado, mas não está fazendo tanto INSERT "s - deve haver um END IF no final da seção" IF @Term = 3 "em vez de apenas um END simples?

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

Respostas:

34 para resposta № 1

Tem a ver com o formulário normal para a linguagem SQL. Se as instruções IF puderem, por definição, solteiro Instrução SQL. No entanto, existe um tipo especial de instrução SQL que pode conter várias instruções SQL, o bloco BEGIN-END.

Se você omitir o bloco begin-end, seu SQL será executado corretamente, mas somente executará a primeira instrução como parte do IF.

Basicamente, isso:

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

é equivalente à mesma coisa com oBEGIN-END block, porque você está apenas executando uma única instrução. No entanto, pela mesma razão que não incluir as chaves em uma instrução if em uma linguagem C é uma má idéia, é sempre preferível usar BEGIN e END.


20 para resposta № 2

Não há ENDIF no SQL.

A instrução diretamente seguindo um IF é executada somente quando a expressão if é verdadeira.

O início ... A construção END é separada do IF. Ele liga várias instruções juntas como um bloco que pode ser tratado como se fossem uma única instrução. Portanto, BEGIN ... END pode ser usado diretamente após um IF e, assim, todo o bloco de código na seqüência BEGIN .... END será executado ou ignorado.

No seu caso eu suspeito que o "(mais código)" após FROM XXXXX é onde está o seu problema.


5 para resposta № 3

De imediato, o código parece certo. E se você tentar usar um "Else" e ver o que acontece?

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

2 para resposta № 4

Se este é o MS Sql Server, então o que você temdeve funcionar bem ... Na verdade, tecnicamente, você não precisa do Begin & End, mas há apenas uma instrução no bloco begin-End ... (eu assumo que @Classes é uma variável de tabela?)

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)

2 para resposta № 5

Você também pode reescrever o código para remover completamente a instrução "If" aninhada.

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)

1 para resposta № 6

A única vez que a segunda inserção em @clases deve falhar ao acionar é se um erro ocorreu na primeira instrução de inserção.

Se esse for o caso, você precisará decidir se a segunda instrução deve ser executada antes da primeira OU se precisar de uma transação para executar uma reversão.


0 para resposta № 7

Se bem me lembro, e mais frequentemente, então eu não faço ... não há suporte a END IF no Transact-Sql. O BEGIN e o END devem fazer o trabalho. Você está recebendo erros?


0 para a resposta № 8

Com base na sua descrição do que você quer fazer,o código parece estar correto como está. ENDIF não é uma palavra-chave de controle de loop SQL válida. Tem certeza de que os INSERTS estão realmente puxando dados para colocar em @Classes? Na verdade, se fosse ruim, simplesmente não seria executado.

O que você pode querer tentar é colocar alguns PRINTdeclarações lá dentro. Coloque uma PRINT acima de cada um dos INSERTS apenas dando algum texto bobo para mostrar que aquela linha está sendo executada. Se você obtiver as duas saídas, então seu SELECT ... INSERT ... é suspeito. Você também pode apenas fazer o SELECT no lugar do PRINT (ou seja, sem o INSERT) e ver exatamente quais dados estão sendo puxados.


-9 para resposta № 9

Francamente isso parece algo que deveria estar na camada de aplicação, não na camada de banco de dados ...