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