Хранимые процедуры и функции: операторы
Список операторов, использующихся в хранимых процедурах и функциях.
Определение и присваивание переменных
Синтаксис
declare имя тип [default значение]; set переменная = значение [, переменная = значение]*;
Примеры
declare finish datetime default now(); set idx = 0; set idx = idx + 1, idy = 0; set name = (select FirstName from Students where SId = id);
- После default -- любое вычисляемое значение.
- В последнем примере мы присвоили переменной значение подзапроса.
- В идеале должны получить единственное значение.
- Если ничего не нашли -- будет not found, если несколько -- что-то из них выберется и запишется в переменную.
Select into
Синтаксис
select ... into переменные from ...
Пример
select FirstName, LastName into FN, LN from Students where SId = id;
- Записывает соответственно переменным полученные значения.
- Нужен в том случае, если хотим записать данные в несколько переменных из одной найденной строчки. Делать это через несколько присваиваний неэффективно.
- Переменные должны быть объявлены, их количества совпадать и иметь соответствующие типы с результатом.
- Нельзя получать больше одного значения, при отсутствии результата переменные заполнятся null-ами.
Ветвления
If
Синтаксис
if условие then операторы [else if условие then операторы]* [else операторы] end if;
Пример
if badDays > 0 then update Accounts set Balance = Balance - amount; set badDays = 0; end if;
Case-оператор
Синтаксис
case выражение [when значение then операторы]+ [else операторы] end case;
Пример
case name when 'Иван' then set name = 'Ивана' when 'Пётр' then set name = 'Петра' else set name = '???' end case;
Case-операция
set name = case name when 'Иван' then 'Ивана' when 'Пётр' then 'Петра' else '???' end case;
- если нет else, а ни один when не сработал, будет null.
Циклы
Метка до цикла может понадобиться для leave и iterate.
Метка после end <loop_name> исключительно для программиста -- по стандарту проверят, что метки совпадают.
While
Синтаксис
[метка:] while условие do операторы end while [метка];
Пример (добавляем 10 студентов).
declare i int default 1; ins: while i <= 10 do insert into Students (Id) values (i); set i = i + 1; end while ins;
Repeat
Синтаксис
[метка:] repeat операторы until условие end repeat [метка];
Пример (делаем то же самое, но с помощью repeat)
declare i int default 1; repeat insert into Students (Id) values (i); set i = i + 1; until i <= 10 end repeat;
Loop
Синтаксис
[метка:] loop операторы end loop [метка];
- Бесконечных циклов не бывает, поэтому мы ожидаем, что цикл завершится с ошибкой (в примере ниже, вероятно, out of memory).
Пример (добавляем бесконечное число студентов)
declare i int default 1; loop insert into Students (Id) values (i); set i = i + 1; end loop;
Leave, iterate
Синтаксис
leave label iterate label
- leave = break, iterate = continue.
- Метка указывает на цикл (он имеет ту же метку), с которым мы проводим эту операцию.
Пример (исправляем прошлый пример с loop)
declare i int default 1; l: loop insert into Students (Id) values (i); if i > 10 then leave l; end if; set i = i + 1; end loop;
Составной оператор
Синтаксис
[метка:] begin определения тело end
Пример
begin declare x int; declare y int; set x = 42; set y = 43; end;
Обработчики ошибок
На самом деле блок begin/end -- неявный "try". Мы можем определить обработчики. Для каждой ошибки может быть не более одного обработчика.
Синтаксис
declare {continue|exit|undo} handler for условие оператор
- continue | exit | undo -- тип обработчика. Соответственно: продолжить выполнение, выйти из блока, откатить изменения и выйти из блока.
- условие -- код ошибки. Синтаксис: sqlstate [value]. Есть зарезервированные и имеющие имена (можно использовать оба варианта):
- sqlwarning -- sqlstate 01xxx
- not found -- sqlstate 02xxx
- sqlexception -- sqlstate yyxxx
- оператор -- код, который должен исполниться при возникновении ошибки.
Примеры:
- Подавление ошибки
begin declare exit handler for not found begin end; ... end;
- Подмена значения
begin declare continue handler for not found set name = '?'; set name = (select FirstName from students where SId = id); ... end;