Хранимые процедуры и функции: операторы — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(color)
м (rollbackEdits.php mass rollback)
 
(не показаны 4 промежуточные версии 2 участников)
Строка 15: Строка 15:
 
  <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);
 
  <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);
  
*После <font color = blue>default</font> -- любое вычисляемое значение.
+
*После <font color = blue>default</font> {{---}} любое вычисляемое значение.
 
*В последнем примере мы присвоили переменной значение подзапроса.
 
*В последнем примере мы присвоили переменной значение подзапроса.
 
*:В идеале должны получить единственное значение.
 
*:В идеале должны получить единственное значение.
*:Если ничего не нашли -- будет [[Хранимые процедуры и функции: операторы#Обработчики ошибок | not found]], если несколько -- что-то из них выберется и запишется в переменную.
+
*:Если ничего не нашли {{---}} будет [[Хранимые процедуры и функции: операторы#Обработчики ошибок | not found]], если несколько {{---}} что-то из них выберется и запишется в переменную.
  
 
== Select into ==
 
== Select into ==
Строка 76: Строка 76:
 
Метка до цикла может понадобиться для [[Хранимые процедуры и функции: операторы # Leave2C iterate | leave и iterate]].
 
Метка до цикла может понадобиться для [[Хранимые процедуры и функции: операторы # Leave2C iterate | leave и iterate]].
  
Метка после end <loop_name> исключительно для программиста -- по стандарту проверят, что метки совпадают.
+
Метка после end <loop_name> исключительно для программиста {{---}} по стандарту проверят, что метки совпадают.
  
 
=== While ===
 
=== While ===
Строка 111: Строка 111:
 
   операторы
 
   операторы
 
  <font color = blue>end</font> <font color = blue>loop</font> [<font color = red>метка</font>];
 
  <font color = blue>end</font> <font color = blue>loop</font> [<font color = red>метка</font>];
*Бесконечных циклов не бывает, поэтому мы ожидаем, что цикл завершится с [ошибкой] (в примере ниже, вероятно, out of memory).
+
*Бесконечных циклов не бывает, поэтому мы ожидаем, что цикл завершится с [[Хранимые процедуры и функции: операторы#Обработчики ошибок | ошибкой]] (в примере ниже, вероятно, out of memory).
  
 
Пример (добавляем бесконечное число студентов)
 
Пример (добавляем бесконечное число студентов)
Строка 156: Строка 156:
  
 
== Обработчики ошибок ==
 
== Обработчики ошибок ==
На самом деле блок <font color = blue>begin</font>/<font color = blue>end</font> -- неявный "try". Мы можем определить обработчики. Для каждой ошибки может быть не более одного обработчика.
+
На самом деле блок <font color = blue>begin</font>/<font color = blue>end</font> {{---}} неявный "try". Мы можем определить обработчики. Для каждой ошибки может быть не более одного обработчика.
  
 
Синтаксис
 
Синтаксис
Строка 162: Строка 162:
 
  <font color = blue>for</font> условие
 
  <font color = blue>for</font> условие
 
  оператор
 
  оператор
*<font color = blue>continue</font> | <font color = blue>exit</font> | <font color = blue>undo</font> -- тип обработчика. Соответственно: продолжить выполнение, выйти из блока, откатить изменения и выйти из блока.
+
*<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>sqlwarning</font> {{---}} sqlstate 01xxx
*:<font color = blue>not </font><font color = blue>found</font> -- sqlstate 02xxx
+
*:<font color = blue>not </font><font color = blue>found</font> {{---}} sqlstate 02xxx
*:<font color = blue>sqlexception</font> -- sqlstate yyxxx
+
*:<font color = blue>sqlexception</font> {{---}} sqlstate yyxxx
*оператор -- код, который должен исполниться при возникновении ошибки.
+
*оператор {{---}} код, который должен исполниться при возникновении ошибки.
  
 
Примеры:
 
Примеры:
Строка 182: Строка 182:
 
   ...
 
   ...
 
  <font color = blue>end</font>;
 
  <font color = blue>end</font>;
 +
 +
== См. также ==
 +
*[[Хранимые функции]]
 +
*[[Хранимые процедуры]]
 +
 +
==Литература==
 +
* ''Дейт К. Введение в системы баз данных (главы 4 и 17)''
 +
* ''Уидом Д., Ульман Д. Основы реляционных баз данных (раздел 7.4)''
 +
* ''Gulutzan P., Pelzer T. SQL-99 complete, really''
 +
** [https://crate.io/docs/sql-99/en/latest/chapters/25.html Chapter 25 – SQL-Invoked Routine]
 +
** [https://crate.io/docs/sql-99/en/latest/chapters/26.html Chapter 26 – PSM: Not Just Persistent Stored Modules]
 +
 +
[[Категория: Базы данных]]

Текущая версия на 19:36, 4 сентября 2022

Список операторов, использующихся в хранимых процедурах и функциях.

Определение и присваивание переменных

Синтаксис

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;

См. также

Литература