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

Материал из Викиконспекты
Перейти к: навигация, поиск
м (error link)
м (end)
Строка 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]
 +
 +
[[Категория: Базы данных]]

Версия 04:56, 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;

См. также

Литература