Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

SUBD Labs 8-14

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
433.06 Кб
Скачать

Лабораторна робота №11

з курсу “СУБД” на тему:

“Написання збережених процедур на мові SQL”

Мета роботи: Навчитися розробляти та виконувати збережені процедури та функції у

MySQL.

Короткі теоретичні відомості.

Більшість СУБД підтримують використання збережених послідовностей команд для виконання часто повторюваних, однотипних дій над даними. Такі збережені процедури дозволяють спростити оброблення даних, а також підвищити безпеку при роботі з базою даних, оскільки в цьому випадку прикладні програми не потребують прямого доступу до таблиць, а отримують потрібну інформацію через процедури.

СУБД MySQL підтримує збережені процедури і збережені функції. Аналогічно до вбудованих функцій (типу COUNT), збережену функцію викликають з деякого виразу і вона повертає цьому виразу обчислене значення. Збережену процедуру викликають за допомогою команди CALL. Процедура повертає значення через вихідні параметри, або генерує набір даних, який передається у прикладну програму.

Синтаксис команд для створення збережених процедур описано нижче.

CREATE

[DEFINER = { користувач | CURRENT_USER }] FUNCTION назва_функції ([параметри_функції ...]) RETURNS тип

[характеристика ...] тіло_функції

CREATE

[DEFINER = { користувач | CURRENT_USER }]

PROCEDURE назва_процедури ([параметри_процедури ...]) [характеристика ...] тіло_процедури

Аргументи:

DEFINER

Задає автора процедури чи функції. За замовчуванням – це CURRENT_USER.

RETURNS

Вказує тип значення, яке повертає функція.

тіло_функції, тіло_процедури

Послідовність директив SQL. В тілі процедур і функцій можна оголошувати локальні змінні, використовувати директиви BEGIN ... END, CASE, цикли тощо. В тілі процедур також можна виконувати транзакії. Тіло функції обов’язково повинно містити команду RETURN і повертати значення.

параметри_процедури:

[ IN | OUT | INOUT ] ім’я_параметру тип

Параметр, позначений як IN, передає значення у процедуру. OUT-параметр передає значення у точку виклику процедури. Параметр, позначений як INOUT, задається при виклику, може бути змінений всередині процедури і зчитаний після її завершення. Типом параметру може бути будь-який із типів даних, що підтримується MySQL.

параметри_функції:

ім’я_параметру тип

У випадку функцій параметри використовують лише для передачі значень у функцію.

При створенні процедур і функцій можна вказувати їхні додаткові характеристики.

характеристика:

LANGUAGE SQL

| [NOT] DETERMINISTIC

| {CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA} | SQL SECURITY {DEFINER | INVOKER}

| COMMENT 'короткий опис процедури'

DETERMINISTIC

Вказує на те, що процедура обробляє дані строго визначеним (детермінованим) чином. Тобто, залежно від вхідних даних, процедура повертає один і той самий результат. Недетерміновані процедури містять функції типу NOW() або RAND(), і результат їх виконання не можна передбачити. За замовчуванням всі процедури і функції є недетермінованими.

CONTAINS SQL | NO SQL

Вказує на те, що процедура містить (за замовчуванням), або не містить директиви SQL.

READS SQL DATA

Вказує на те, що процедура містить директиви, які тільки зчитують дані з таблиць.

MODIFIES SQL DATA

Вказує на те, що процедура містить директиви, які можуть змінювати дані в таблицях.

SQL SECURITY

Задає рівень прав доступу, під яким буде виконуватись процедура. DEFINER – з правами автора процедури (задано за замовчуванням), INVOKER – з правами користувача, який викликає процедуру. Щоб запускати збережені процедури і функції, користувач повинен мати права EXECUTE.

При створенні процедур і функцій у командному рядку клієнта MySQL, потрібно перевизначити стандартний символ завершення вводу директив ";", щоб мати можливість ввести всі директиви процедури. Це робиться за допомогою команди DELIMITER. Наприклад,

DELIMITER |

означає, що завершення вводу процедури буде позначатись символом "|".

Нижче наведено синтаксис додаткових директив MySQL, які дозволяють розробляти нескладні програми на мові SQL.

DECLARE назва_змінної тип_змінної [DEFAULT значення_за_замовчуванням]

Оголошення змінної заданого типу.

SET назва_змінної = вираз

Присвоєння змінній значення.

IF умова THEN директиви

[ELSEIF умова THEN директиви] ...

[ELSE директиви2] END IF

Умовний оператор. Якщо виконується вказана умова, то виконуються відповідні їй директиви, в протилежному випадку виконуються директиви2.

CASE вираз

WHEN значення1 THEN директиви1 [WHEN значення2 THEN директиви2] ...

[ELSE директиви3] END CASE

Оператор умовного вибору. Якщо вираз приймає значення1, виконуються директиви1, якщо приймає значення2 – виконуються директиви2, і т.д. Якщо вираз не прийме жодного зі значень, виконуються директиви3.

[мітка:] LOOP

директиви

END LOOP

Оператор безумовного циклу. Вихід з циклу виконується командою LEAVE мітка.

REPEAT

директиви

UNTIL умова END REPEAT

WHILE умова DO

директиви

END WHILE

Оператори REPEAT і WHILE дозволяють організувати умовні цикли, які завершуються при виконанні деякої умови.

Хід роботи.

Напишемо функції, які будуть обгортками стандартних функцій шифрування, та процедуру, яка буде обчислювати кількість написаних автором повідомлень у кожній категорії за вказаний проміжок часу.

1. Функції шифрування/дешифрування із заданим ключем.

CREATE FUNCTION mycms_encode (pass CHAR(48))

RETURNS TINYBLOB

RETURN AES_ENCRYPT(pass, 'key-key');

CREATE FUNCTION mycms_decode (pass TINYBLOB)

RETURNS CHAR(48)

RETURN AES_DECRYPT(pass, 'key-key');

2. Процедура повинна рахувати кількість повідомлень автора написаних за певний проміжок часу у кожній з існуючих категорій. Для цього потрібно відібрати всі повідомлення та їх категорії за автором та часом написання. Потім згрупувати вибрані повідомлення за категоріями та порахувати кількість повідомлень. У процедуру потрібно передати ім’я автора, а також першу і другу дату.

Перед основними директивами додамо перевірку коректності задання початкової і кінцевої дати (IF date1<=date2 THEN…). Результати обчислень будуть записуватись у таблицю Stats, яку процедура завжди очищує (командою TRUNCATE mycms.stats) і заповнює з нуля.

DELIMITER //

CREATE PROCEDURE mycms_count (IN name CHAR(19), IN date1 DATE, IN date2 DATE)

BEGIN

DECLARE error CHAR;

SET error = 'Некоректно задані дати';

IF (date1<=date2) THEN

BEGIN

CREATE TABLE IF NOT EXISTS mycms.stats (category CHAR(20), amount INT UNSIGNED);

TRUNCATE mycms.stats;

INSERT INTO mycms.stats SELECT cname AS category, COUNT(message.messageID) AS amount

FROM ((author INNER JOIN message)

INNER JOIN message_category) INNER JOIN category ON author.login=name

AND author.authorID=message.authorID

AND message.messageID=message_category.messageID AND message_category.categoryID=category.categoryID WHERE message.posted BETWEEN date1 AND date2

GROUP BY category;

END;

ELSE SELECT error;

END IF; END// DELIMITER ;

3. Після створення функцій і процедури перевіримо їх роботу:

SELECT login, mycms_decode(password) FROM author LIMIT 4;

CALL mycms_count('user1', '2008-01-01', '2009-05-05');

SELECT * FROM stats;

Результат роботи процедури – таблиця stats:

CALL mycms_count('user1', '2010-01-01', '2009-05-05');

Результат виклику процедури:

Висновок: на цій лабораторній роботі я навчився розробляти та використовувати збережені процедури і функції у СУБД MySQL.

Лабораторна робота №12

з курсу “СУБД” на тему:

“Розробка та застосування транзакцій”

Мета роботи: Навчитися використовувати механізм транзакцій у СУБД MySQL. Розробити SQL запити, які виконуються як єдине ціле в рамках однієї транзакції.

Короткі теоретичні відомості.

Транзакція – це сукупність директив SQL, які виконуються як єдине ціле з можливістю відміни результатів їх виконання. Зміни в таблицях записуються у базу даних лише після успішного виконання всіх директив транзакції. Інакше, всі зроблені зміни ігноруються. Це дозволяє уникати помилок при маніпулюванні великими обсягами записів, зберігати цілісність даних при помилках під час додавання, видалення, модифікації значень у різних таблицях і полях тощо. СУБД MySQL також підтримує глобальні розподілені транзакції, які виконуються на декількох базах даних, або на різних серверах баз даних (ХА-транзакції).

Для організації транзакцій в MySQL використовують такі директиви, як SET autocommit, START TRANSACTION, COMMIT і ROLLBACK.

START TRANSACTION

Вказує на початок транзакції. Директива вимикає автоматичне збереження змін для всіх подальших запитів, поки не буде виконано команду COMMIT, або ROLLBACK.

COMMIT

Зберегти зміни, зроблені даною транзакцією.

ROLLBACK

Відмінити дану транзакцію і зроблені нею зміни у базі даних. Слід зауважити, що зміни у схемі бази даних не можна відмінити, тобто результат видалення, зміни або створення таблиці завжди зберігається.

SET autocommit=0

Вимикає автоматичне збереження змін для поточної сесії зв’язку з сервером БД. За замовчуванням, зміни зберігаються автоматично, тобто результат виконання запиту, який змінює таблицю, одразу записується на диск без можливості відміни операції.

AND CHAIN

Одразу після завершення даної транзакції розпочати виконання наступної.

RELEASE

Одразу після виконання даної транзакції завершити поточну сесію зв’язку з сервером.

Транзакції можна розбивати на окремі логічні частини, оголошуючи так звані точки збереження. Це дозволяє відміняти результати виконання не всієї транзакції, а лише тих запитів, які виконувались після оголошеної точки збереження (SAVEPOINT).

SAVEPOINT мітка

Оголошує точку збереження всередині транзакції та задає її назву.

ROLLBACK TO [SAVEPOINT] мітка

Відміняє результати виконання запитів, вказаних після даної точки збереження.

RELEASE SAVEPOINT мітка

Видаляє точку збереження.

Хід роботи.

В ході роботи, потрібно продемонструвати успішне і неуспішне виконання транзакції. Розробимо транзакцію, яка буде вносити дані в таблицю Author i Role. Транзакція буде

відміняти всі зміни у таблицях при виникненні помилки чи іншої суперечливості.

1. Відміна транзакції.

Транзакція складається з чотирьох запитів на додавання нових користувачів у групу "ugroup" та "sugroup3". При цьому, групи "sugroup3" з roleID=9 в базі даних не існує, а отже, транзакція не виконується.

START TRANSACTION;

INSERT INTO mycms.author VALUE (NULL, NULL, 'user7', 'u7pass', '2008-04-16', 'user7@kml.com', NULL, 2);

INSERT INTO mycms.author VALUE (NULL, NULL, 'user8', 'u8pass', '2009-04-22', 'user8@kml.com', NULL, 2);

INSERT INTO mycms.author VALUE (NULL,NULL, 'superuser4', 'suser4_pass', '2009-05-01', 'suser4@gl.com', NULL, 9); INSERT INTO mycms.author VALUE (NULL,NULL, 'suser5', 'suuser5_pass', '2009-05-01', 'suser5@gl.com', NULL, 9);

COMMIT;

Відповідь сервера:

#1452 - Cannot add or update a child row: a foreign key constraint fails (`mycms/author`, CONSTRAINT `author_role` FOREIGN KEY (`roleID`) REFERENCES `role` (`roleID`) ON DELETE NO ACTION ON UPDATE NO ACTION)

2. Успішна транзакція.

Транзакція складається з запитів на додавання тих самих користувачів у групу "ugroup" та "sugroup3" після створення у таблиці Role групи "sugroup3".

INSERT INTO role

VALUE (NULL,'SUGroup3', 'read, write, changeown, groupadmin');

START TRANSACTION;

INSERT INTO mycms.author VALUE (NULL, NULL, 'user7', 'u7pass', '2008-04-16', 'user7@kml.com', NULL, 2);

INSERT INTO mycms.author VALUE (NULL, NULL, 'user8', 'u8pass', '2009-04-22', 'user8@ml.com', NULL, 2);

INSERT INTO mycms.author VALUE (NULL,NULL, 'superuser4', 'suser4_pass', '2009-05-01', 'suser4@gl.com', NULL, 9); INSERT INTO mycms.author VALUE (NULL,NULL, 'suser5', 'suuser5_pass', '2009-05-01', 'suser5@gl.com', NULL, 9);

COMMIT;

Результат успішного додавання чотирьох користувачів у таблицю показано нижче:

SELECT * FROM author LIMIT 9, 5;

Висновок: На цій лабораторній роботі я ознайомився із механізмом транзакцій у СУБД

MySQL.

Лабораторна робота №13

з курсу “СУБД” на тему:

“Розробка та застосування тригерів”

Мета роботи: Розробити SQL запити, які моделюють роботу тригерів: каскадне знищення, зміна та доповнення записів у зв’язаних таблицях.

Короткі теоретичні відомості.

Тригер – це спеціальний вид користувацької процедури, який виконується автоматично при певних діях над таблицею, наприклад, при додаванні чи оновленні даних. Кожен тригер асоційований з конкретною таблицею і подією. Найчастіше тригери використовуються для перевірки коректності вводу нових даних та підтримки складних обмежень цілісності. Крім цього їх використовують для автоматичного обчислення значень полів таблиць, організації перевірок для захисту даних, збирання статистики доступу до таблиць баз даних чи реєстрації інших подій.

Для створення тригерів використовують директиву CREATE TRIGGER.

Синтаксис:

CREATE

[DEFINER = { користувач | CURRENT_USER }]

TRIGGER ім’я_тригера час_виконання подія_виконання ON назва_таблиці FOR EACH ROW тіло_тригера

Аргументи:

DEFINER

Задає автора процедури чи функції. За замовчуванням – це CURRENT_USER.

ім’я_тригера

Ім’я тригера повинно бути унікальним в межах однієї бази даних.

час_виконання

Час виконання тригера відносно події виконання. BEFORE – виконати тіло тригера до виконання події, AFTER – виконати тіло тригера після події.

подія_виконання

Можлива подія – це внесення (INSERT), оновлення (UPDATE), або видалення (DELETE) рядка з таблиці. Один тригер може бути пов’язаний лише з однією подією. Команда AFTER INSERT, AFTER UPDATE, AFTER DELETE визначає виконання тіла тригера відповідно після внесення, оновлення, або видалення даних з таблиці. Команда

BEFORE INSERT, BEFORE UPDATE, BEFORE DELETE визначає виконання тіла тригера відповідно до внесення, оновлення, або видалення даних з таблиці.

ON назва_таблиці

Таблиця, або віртуальна таблиця (VIEW), для якої створюється даний тригер. При видалені таблиці з бази даних, автоматично видаляються всі пов’язані з нею тригери.

FOR EACH ROW тіло_тригера

Задає набір SQL директив, які виконує тригер. Тригер викликається і виконується для кожного зміненого рядка. Директиви можуть об’єднуватись командами BEGIN … END та містити спеціальні команди OLD та NEW для доступу до попереднього та нового значення поля у зміненому рядку відповідно. В тілі тригера дозволено викликати збережені процедури, але заборонено використовувати транзакції, оскільки тіло тригера автоматично виконується як одна транзакція.

NEW.назва_поля

Повертає нове значення поля для зміненого рядка. Працює лише при подіях INSERT та UPDATE. У тригерах, які виконуються перед (BEFORE) подією можна змінити нове значення поля командою SET NEW.назва_поля = значення.

OLD.назва_поля

Повертає старе значення поля для зміненого рядка. Можна використовувати лише при подіях UPDATE та DELETE. Змінити старе значення поля не можливо.

Щоб видалити створений тригер з бази даних, потрібно виконати команду

DROP TRIGGER назва_тригера.

Хід роботи.

Потрібно розробити тригери, які виконуватимуть наступні дії.

1.Каскадне оновлення таблиці користувачів при видаленні ролі з таблиці Role.

2.Шифрування паролю користувача під час внесення в таблицю.

3.Тригер для таблиці Session, який буде фіксувати у таблиці Author дату останнього входу користувача в систему.

1. Каскадне оновлення таблиці користувачів при видаленні ролі з таблиці Role. Діюче обмеження зовнішнього ключа при видалені ролі встановлює для користувача невизначену роль (значення NULL). Натомість, за допомогою тригера, користувачеві потрібно присвоювати певну роль за замовчуванням (роль Guests з roleID=4).

CREATE

TRIGGER role_delete BEFORE DELETE ON mycms.role FOR EACH ROW

UPDATE mycms.author SET roleID=4 WHERE roleID=OLD.roleID;

Перевіримо роботу тригера, видаливши роль з номером 9:

DELETE FROM mycms.role WHERE roleID=9;

SELECT * FROM mycms.author LIMIT 10, 5;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]