SQL "IF", "BEGIN", "END", "END IF"?
Не человек SQL вообще. Имейте следующий код, который написал консультант.
Во-первых, он гарантирует, что выбрана только начальная школа - тогда, после BEGIN, если переменная @Term равна 3, мы хотим сделать материал в этом выражении IF. Вот проблема. Когда @Term не = 3, мы все равно хотим опуститься и сделать часть SECOND INSERT INTO @Classes. FYI - Термин = 3, когда он выполняется, но он не делает оба INSERT - должен ли быть END IF в конце этого раздела "IF @Term = 3" вместо простого 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
Ответы
Ответ 1
Это связано с нормальной формой для языка 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
, потому что вы выполняете только один оператор. Однако по той же причине, по которой не включать в фигурные скобки оператора IF
в языке, подобном C, плохая идея, всегда предпочтительнее использовать BEGIN
и END
.
Ответ 2
В SQL отсутствует ENDIF.
Операция непосредственно после IF выполняется только тогда, когда выражение if истинно.
Конструкция BEGIN... END отделена от IF. Он связывает несколько операторов вместе как блок, который можно трактовать так, как если бы это был один оператор. Следовательно, BEGIN... END может использоваться непосредственно после IF и, следовательно, весь блок кода в BEGIN.... END-последовательность будет либо выполнена, либо пропущена.
В вашем случае я подозреваю, что "(больше кода)", следующий за XXXXX, является вашей проблемой.
Ответ 3
Сразу же код выглядит правильно. Что делать, если вы пытаетесь использовать "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
Ответ 4
Если это MS Sql Server, то то, что у вас есть, должно работать нормально...
На самом деле, технически, вы вообще не нуждаетесь в Begin и End, snce там только один оператор в блоке 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)
Ответ 5
Вы также можете переписать код, чтобы полностью удалить вложенный оператор "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)
Ответ 6
Если я правильно помню, и чаще всего не делаю... в Transact-Sql нет поддержки END IF. BEGIN и END должны выполнить эту работу. Вы получаете ошибки?
Ответ 7
Единственный раз, когда вторая вставка в @clases не запускается, - это ошибка в первом вставке.
Если это так, вам нужно решить, должен ли второй оператор работать до первого OR, если вам нужна транзакция для выполнения отката.
Ответ 8
На основе вашего описания того, что вы хотите сделать, код кажется правильным, как есть. ENDIF не является допустимым ключевым элементом управления циклом SQL. Вы уверены, что INSERTS на самом деле вытаскивают данные для размещения в @Classes? На самом деле, если бы это было плохо, это просто не сработало.
Что вы можете попробовать, так это добавить несколько инструкций PRINT. Поместите ПЕЧАТЬ над каждым из ВСТАВКИ, просто выведя какой-то глупый текст, чтобы показать, что эта строка выполняется. Если вы получаете оба выхода, то ваш SELECT... INSERT... является подозрительным. Вы также можете просто сделать SELECT вместо PRINT (то есть без INSERT) и точно посмотреть, какие данные вытаскивают.
Ответ 9
Откровенно это похоже на что-то, что должно быть на уровне приложения, а не на уровне базы данных...