Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Основное / Письменные лекции по дисциплине «Базы данных»

.pdf
Скачиваний:
98
Добавлен:
29.01.2021
Размер:
939.56 Кб
Скачать

Последняя часть CREATE PROCEDURE — это пара скобок содержит список параметров. Поскольку эта процедура не имеет никаких параметров, список пуст.

Следующая часть SELECT * FROM JOBS; $$ — это последний оператор в синтаксисе хранимых процедур MySQL. Точка с запятой здесь не является обязательной, так как реальным окончанием оператора является $$.

Вызов процедуры:

CALL имя_процедуры([параметр [, ...]])

CALL имя_процедуры[()]

MySQL хранимые процедуры, которые не принимают аргументов, могут вызываться без скобок. Поэтому CALL job_data() равносильно

CALL job_data.

Создание функции происходит следующим образом:

CREATE FUNCTION имя_функции ([параметр_функции [, ...]]) RETURNS тип [характеристика ...] тело_подпрограммы

Удаление процедуры/функции используется для сброса в MySQL

вызванной хранимой процедуры или функции.

DROP {PROCEDURE | FUNCTION} [IF EXISTS] имя_процедуры

3.2. Переменные

Переменные бывают пользовательскими (такая переменная создается в момент присвоения ей значения и хранится до завершения соединения с сервером; пишется со знаком @, например, @total), переменными хранимого кода (имеют ограниченную область видимости; пишется без знака @) и системными.

Пользовательская переменная:

SET @total = 5;

Переменная хранимого кода:

DECLARE total INT DEFAULT 5;

или

DECLARE total INT;

SET total = 5;

Системная переменная может быть глобальной или переменной сеанса.

Глобальная системная переменная:

SET GLOBAL total = 5;

или

SET @@global.total = 5;

Системная переменная сеанса:

SET total = 5;

или

SET SESSION total = 5;

или

SET @@total = 5;

или

SET @@local.total = 5;

В следующем примере показано использование пользовательских переменных внутри хранимой процедуры.

mysql>

DELIMITER $$

mysql>

CREATE PROCEDURE my_procedure_User_Variables()

->

BEGIN

->

SET @x = 15;

->

SET @y = 10;

->

SELECT @x, @y, @x - @y;

->

END $$

Query OK, 0 rows affected (0.32 sec) mysql> DELIMITER ; $$

Теперь выполним процедуру:

mysql> CALL my_procedure_User_Variables();

+------

+------

+---------

+

| @x

| @y

| @x - @y |

+------

+------

+---------

+

|

15 |

10 |

5

|

+

------

+

------+

---------

+

1

row

in set (0.01 sec)

 

Query

OK, 0 rows affected (0.01 sec)

3.3. Параметры процедуры

Синтаксис процедуры:

CREATE [DEFINER = { пользователь | CURRENT_USER }] PROCEDURE имя_процедуры ([параметр_процедуры[,...]]) [характеристики ...] тело_подпрограммы

параметр_процедуры: [ IN | OUT | INOUT ] имя_парамета type

Варианты синтаксиса:

CREATE PROCEDURE имя_процедуры () …

CREATE PROCEDURE имя_процедуры ([IN] имя_параметра type)… CREATE PROCEDURE имя_процедуры ([OUT] имя_параметра type)… CREATE PROCEDURE имя_процедуры ([INOUT] имя_параметра type)…

В первом примере список параметров пуст.

Во втором примере параметр IN передает значение в процедуру. Эта процедура может изменить значение. Но, когда процедура возвращает значение, оно не будет видно для вызывающего агента.

Втретьем примере параметр OUT передает значение из процедуры обратно вызывающему агенту. Его начальное значение в процедуре NULL, и, когда процедура возвращает значение, оно видно вызывающему агенту.

Вчетвертом примере параметр INOUT инициализируется вызывающим агентом, он может быть изменен процедурой, и когда процедура возвращает значение, любые изменения, произведенные MySQL хранимой процедурой, будут видны вызывающему агенту.

Впроцедуре каждый параметр по умолчанию является параметром IN. Чтобы изменить это, используйте перед именем параметра ключевое

слово OUT или INOUT.

Пример параметра IN.

mysql> CREATE PROCEDURE my_proc_IN (IN var1 INT)

-> BEGIN

-> SELECT * FROM jobs LIMIT var1;

-> END$$

Query OK, 0 rows affected (0.00 sec)

LIMIT используется для ограничения количества возвращаемых записей таблицы jobs на основании предельного значения var1.

Чтобы выбрать первые две строки из таблицы jobs выполним следующую команду:

mysql> CALL

my_proc_in(2)$$

 

 

 

 

 

+---------

 

+-------------------------------

 

+------------

 

+------------

 

+

| JOB_ID

|

JOB_TITLE

| MIN_SALARY

| MAX_SALARY |

+---------

 

+-------------------------------

 

+------------

 

+------------

 

+

| AD_PRES

|

President

|

20000

|

40000

|

| AD_VP

|

Administration Vice President |

15000

|

30000

|

+---------

 

+-------------------------------

 

+------------

 

+------------

 

+

2

rows in

set (0.00 sec)Query OK, 0 rows affected (0.03 sec)

 

 

Пример параметра OUT.

Дальше представлен MySQL хранимой процедуры пример, в котором используется параметр OUT. В рамках процедуры MySQL функция MAX() извлекает максимальную зарплату из столбца MAX_SALARY

таблицы jobs:

mysql> CREATE PROCEDURE my_proc_OUT (OUT highest_salary INT) -> BEGIN

-> SELECT MAX(MAX_SALARY) INTO highest_salary FROM JOBS; -> END$$

Query OK, 0 rows affected (0.00 sec)

В теле процедуры параметр получает самую высокую зарплату из столбца MAX_SALARY. После вызова процедуры слово OUT сообщает СУБД, что значение исходит от процедуры. highest_salary — это имя выходного параметра и в операторе CALL мы передали его значение переменной сеанса с именем @M:

mysql> CALL my_proc_OUT(@M)$$

Query OK, 1 row affected (0.03 sec)

mysql> SELECT @M$$+-------

+

| @M

|

 

+-------

+

 

| 40000 |

 

+-------

+

 

1 row in set (0.00 sec)

 

Пример параметра INOUT.

В следующем примере показана простая хранимая процедура MySQL, которая использует параметр INOUT и параметр IN. Пользователь предоставляет 'M' или 'F' через параметр IN (emp_gender) для подсчета количества сотрудников мужского или женского пола из таблицы user_details. Параметр INOUT (mfgender) возвращает результат пользователю. Вот код и результат выполнения процедуры:

mysql> CALL my_proc_OUT(@M)$$

 

Query OK, 1 row affected (0.03 sec)

 

mysql> CREATE PROCEDURE my_proc_INOUT

(INOUT mfgender

INT, IN emp_gender CHAR(1))

 

 

-> BEGIN

 

 

-> SELECT COUNT(gender) INTO

mfgender FROM

user_details WHERE gender = emp_gender;

 

 

-> END$$

 

Query OK, 0 rows affected (0.00 sec)

 

Теперь проверяем количество сотрудников мужского и женского

пола в указанной таблице:

 

mysql> CALL my_proc_INOUT(@C,'M')$$

 

Query OK, 1 row affected (0.02 sec)

 

mysql> SELECT @C$$

 

+------+

 

| @C

|

 

+------+

 

|

3 |

 

+------+

 

1 row in set (0.00 sec)

mysql> CALL my_proc_INOUT(@C,'F')$$

Query OK, 1 row affected (0.00 sec) mysql> SELECT @C$$

+------+

| @C |

+------+

|

1 |

+------+

1 row in set (0.00 sec)

3.4. Операторы IF и CASE

Оператор IF реализует базовую конструкцию условия, он должен заканчиваться точкой с запятой. Существует также функция IF(), которая отличается от оператора IF. Вот синтаксис оператора IF:

IF условие THEN оператор(ы)

[ELSEIF условие THEN оператор(ы)] ...

[ELSE оператор(ы)]

END IF

Если условие выполняется, выполняются операторы соответствующих блоков THEN или ELSE IF.

Если условие не удовлетворяется, выполняются операторы блока ELSE. Каждый оператор состоит из одного или нескольких операторов SQL; пустые операторы не допускается.

Оператор CASE используется для создания внутри хранимой процедуры MySQL сложной условной конструкции. Оператор CASE не может содержать блок ELSE NULL и должен закрываться END CASE, а не

END. Синтаксис:

CASE значение

WHEN значение THEN список_операторов

[WHEN значение THEN список_операторов] ...

[ELSE список_операторов] END CASE

список_операторов
список_операторов

или:

CASE

WHEN условие_поиска THEN список_операторов

[WHEN условие_поиска THEN список_операторов] ...

[ELSE список_операторов] END CASE

Пояснение: первый синтаксис.

Значение — это выражение, которое сравнивается со значением в каждом блоке WHEN, пока они не будут равны. При найденном соответствии значений выполняется

соответствующего блока THEN.

Если значения не равны, тогда выполняется блока ELSE, если таковой имеется.

Пояснение: второй синтаксис.

Каждое выражение блока условие_поиска оценивается, пока одно из них не будет истинно. В этот момент выполняется список_операторов соответствующего блока THEN.

Если ни одно из выражений условие_поиска не истинно, тогда выполняется список_операторов блока ELSE, если таковой имеется. Каждый список_операторов состоит из одного или нескольких операторов SQL; пустой список_операторов не допускается.

Пример использования CASE.

DELIMITER $$

CREATE PROCEDURE `hr`.`my_proc_CASE` (INOUT no_employees INT, IN salary INT) BEGIN

CASE

WHEN (salary>10000)

THEN (SELECT COUNT(job_id) INTO no_employees

FROM jobs

WHERE min_salary>10000);

WHEN (salary<10000)

THEN (SELECT COUNT(job_id) INTO no_employees

FROM jobs

WHERE min_salary<10000);

ELSE (SELECT COUNT(job_id) INTO no_employees

FROM jobs WHERE min_salary=10000);

END CASE;

END$$

В приведенной выше процедуре мы передаем переменную salary через параметр IN. Есть оператор CASE с двумя блоками WHEN и ELSE, который проверяет условия и возвращает значение счетчика в no_employees. no_employees — число сотрудников, в процедуру подается изначально пустое.

Выполним процедуру через командную строку MySQL.

Подсчитаем количество сотрудников, удовлетворяющих следующим условиям:

MIN_SALARY > 10000

MIN_SALARY < 10000

MIN_SALARY = 10000

Количество сотрудников, чья зарплата превышает 10000:

mysql> CALL my_proc_CASE(@C,10001);

Query OK, 1 row affected (0.00 sec) mysql> SELECT @C;

+------+

| @C |

+------+

|

2 |

+------+

1 row in set (0.00 sec)

Количество сотрудников, чья зарплата меньше, чем 10000:

mysql> CALL my_proc_CASE(@C,9999);

Query OK, 1 row affected (0.00 sec)

mysql> SELECT @C; +------+

| @C | +------+ | 16 | +------+

1 row in set (0.00 sec)

Количество сотрудников, чья зарплата равна 10000:

mysql> CALL my_proc_CASE(@C,10000);

Query OK, 1 row affected (0.00 sec) mysql> SELECT @C;

+------+

| @C |

+------+

|

1 |

+------+

1 row in set (0.00 sec)

3.5. Оператор RETURN

Оператор RETURN завершает выполнение хранимой функции MySQL и возвращает агенту, вызвавшему функцию, значение expr. В хранимой функции должен содержаться, по крайней мере, один оператор RETURN.

Если функция имеет несколько точек выхода, она может содержать больше одного RETURN. Синтаксис следующий:

RETURN expr

Лекция 4. Транзакции. Уровни изоляции. Блокировки.

Понятие транзакции;

Операторы транзакции;

Уровни изоляции (изолированности) транзакций;

Тест ACID;

Механизм блокировок;

Взаимоблокировки;

Ведение журнала транзакций.

4.1. Понятие транзакции

Транзакция — это операция, состоящая из одного или нескольких запросов к базе данных. Суть транзакций — обеспечить корректное выполнение всех запросов в рамках одной транзакции, а также обеспечить механизм изоляции транзакций друг от друга для решения проблемы совместного доступа к данным.

Любая транзакция либо выполняется полностью, либо не выполняется вообще.

В транзакционной модели есть два фундаментальных понятия: COMMIT и ROLLBACK. COMMIT означает фиксацию всех изменений в транзакции. ROLLBACK означает отмену (откат) изменений, произошедших в транзакции.

При старте транзакции все последующие изменения сохраняются во временном хранилище. В случае выполнения COMMIT, все изменения, выполненные в рамках одной транзакции, сохраняются в физическую БД. В случае выполнения ROLLBACK произойдет откат и все изменения, выполненные в рамках этой транзакции, не сохранятся.

В MySQL транзакции поддерживаются только таблицами InnoDB. Таблицы MyISAM транзакции не поддерживают. В InnoDB по умолчанию включен AUTOCOMMIT, это значит, что, пока транзакция не начата явно, каждый запрос автоматически выполняется в отдельной транзакции.