При сравнении проверяемого значения с набором других можно использовать более компактную форму выражения CASE. Эту форму полезно использовать внутри оператора SELECT или UPDATE, когда в столбце таблицы содержится ограниченное число разных значений и нужно связать с каждым из них соответствующее значение результата CASE. Если использовать выражение CASE таким образом, то оно будет иметь следующий синтаксис:
CASE значение_n
WHEN значенив1 THEN результат1
WHEN значение2 THEN результат2
...
WHEN значение_n THEN результат_n
ELSE результат_х
END
Если проверяемое значение (значение_n) равно значению1, то выражение принимает значение результат1. А если значение_n не равно значению1, а значению2, то выражение принимает значение результат2. Все значения, предназначенные для сравнения, проверяются сверху вниз, по направлению к значению_n, пока не будет найдено то из них, которое равно значению_n. Если же такое значение найдено не будет, то выражение принимает значение результат_х. И опять, если необязательное предложение ELSE отсутствует и ни одно из значений, предназначенных для сравнения, не равно проверяемому, то выражение принимает неопределенное значение.
Чтобы понять, как работает форма CASE со значениями, проанализируйте пример с таблицей, в которой находятся фамилии и звания офицеров. Требуется получить их список, в котором перед фамилиями офицеров стояли бы аббревиатуры их званий. Для сравнения будут использоваться такие звания: генерал (general), полковник (colonel), подполковник (lieutenant colonel), майор (major), капитан (captain), старший лейтенант (first lieutenant), лейтенант (second lieutenant). И наконец, тот, у кого какое-либо другое звание, в списке будет просто назван "господином" (Mr.). Список создается с помощью следующего оператора:
SELECT CASE RANK
WHEN ' general' THEN 'Gen.'
WHEN 'colonel' THEN 'Col.'
WHEN 'lieutenant colonel' THEN 'Lt. Col.
WHEN 'major' THEN 'Maj.'
WHEN ' captain' THEN 'Capt. '
WHEN 'first lieutenant' THEN '1st. Lt.
WHEN 'second lieutenant' THEN '2nd. Lt.
ELSE 'Mr. '
END,
LAST_ NAME
FROM OFFICERS ;
Результат должен быть примерно такой:
Capt. Midnight
Col. Sanders
Gen. Schwarzkopf
Maj. Disaster
Mr. Nimitz
Честер Нимиц был адмиралом во флоте Соединенных Штатов во время Второй мировой войны. Так как в выражении CASE его звания нет, то оно определяется предложением ELSE.
Вот еще пример. Предположим, что капитан Миднайт получает повышение в звании и становится майором. Требуется сделать соответствующие изменения в базе данных OFFICERS (офицеры). Предположим, что в переменной officerjastjiame (фамилия офицера) находится значение 'Midnight', а в переменной new_rank (новое звание) — целое значение (4), которое, согласно следующей таблице, соответствует новому званию Миднайта.
Тогда ввести данные о повышении можно с помощью следующего кода SQL:
UPDATE OFFICERS
SET RANK = CASE :new_rank
WHEN 1 THEN 'general'
WHEN 2 THEN 'colonel'
WHEN 3 THEN ' lieutenant colonel'
WHEN 4 THEN 'major'
WHEN 5 THEN 'captain'
WHEN 6 THEN 'first lieutenant'
WHEN 7 THEN 'second lieutenant'
WHEN 8 THEN'Mr. '
END
WHERE LAST_NAME = :officer_last_name ;
new_rank | Звание |
1 | general |
2 | colonel |
3 | lieutenant colonel |
4 | major |
5 | captain |
6 | first lieutenant |
7 | second lieutenant |
8 | Mr. |
Для выражения CASE со значениями есть еще один синтаксис:
CASE
WHEN значение_n = значение1 THEN результат1
WHEN значвние_n = значение2 THEN результат2
...
WHEN значение_n = значвние_n THEN результат_n
ELSE результат_х
END