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

Материал из Викиконспекты
Перейти к: навигация, поиск
(init)
 
(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.
  
 
== Циклы ==
 
== Циклы ==
Метка до цикла может понадобиться для [[Хранимые процедуры и функции: операторы # Leave, iterate | leave и iterate]].
+
Метка до цикла может понадобиться для [[Хранимые процедуры и функции: операторы # Leave2C iterate | leave и iterate]].
  
Метка после end <loop name> исключительно для программиста -- по стандарту проверят, что метки совпадают.
+
Метка после 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]. Есть зарезервированные и имеющие имена (можно использовать оба варианта):
**sqlwarning -- sqlstate 01xxx
+
*:<font color = blue>sqlwarning</font> -- sqlstate 01xxx
**not found -- sqlstate 02xxx
+
*:<font color = blue>not </font><font color = blue>found</font> -- sqlstate 02xxx
**sqlexception -- sqlstate yyxxx
+
*:<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;