Konspekt_lektsiy_BD_amp_amp_SD
.pdf
|
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
101 |
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m |
y |
sum_sal |
prior_year |
p_y_% |
next_year |
n_y_% |
|
|
12 |
1980 |
1000 |
1000 |
100 |
3400 |
340 |
|
|
12 |
1982 |
3400 |
1000 |
29 |
4650 |
137 |
|
|
12 |
1985 |
4650 |
3400 |
73 |
6150 |
132 |
|
|
12 |
1990 |
6150 |
4650 |
76 |
6150 |
100 |
|
В прикладі запит логічно розбито на вісім підзапитів, які використовуються як віртуальні таблиці в окремих підзапитах:
m_y_sal |
— підзапит зберігає зарплату співробітників за місяцями та роками; |
|
m_y_sal_sum |
— підзапит зберігає суму зарплат співробітників за місяцями та рока- |
|
|
|
ми; |
month_list |
— підзапит зберігає множину всіх номерів місяців через рекурсивний |
|
|
|
виклик; |
year_list |
— |
підзапит зберігає множину років прийняття співробітників на ро- |
|
|
боту; |
month_year_list |
— |
підзапит зберігає множину місяців за всіма роками прийняття |
|
|
співробітників на роботу. |
Підтримка механізму об’єктно-реляційних зв’язків в PostgreSQL
Об’єктно-реляційні зв’язки між таблицями, створення яких було розглянуто у відповідному параграфі (див. стор. 64), накладають певні обмеження на маніпулювання даними в таких таблицях.
Зокрема, внесення даних в таблиці-нащадки не виконує автоматичне внесення в табли- цю-предка, але вони логічно видимі в ній. Так у результаті виконання запиту
INSERT INTO Master
VALUES(2, 'Мікулінська', 'Марія', 'Геннадіївна', 1, 'ОІ', 1, NULL, NULL, 'Тема12');
рядок по студенту буде видно і в таблиці Student.
Для управлення видимістю рядків у таблиці-предку, які були створені в таблицінащадку, використовується оператор ONLY, що передує імені таблиці.
Наприклад, для отримання вмісту тільки таблиці-предка Student без зачіпання таблицінащадка Master використовується запит:
SELECT * FROM ONLY Student;
Наприклад, для оновлення рядків тільки таблиці Student без зачіпання рядків таблиці Master використовується запит:
UPDATE ONLY Student SET SecondName = 'Глава' WHERE kod = 1;
А для поновлення рядків таблиці Student і рядків таблиці Master використовується стандартний запит:
UPDATE Student SET SecondName = 'Глава'WHERE Kod = 1;
Демонстраційний приклад
Запишіть SQL-запити з використанням підзапитів для маніпулювання даними з таблиць, що створені у завданні „Демонстраційний приклад“ розд. „Мова визначення даних
(МВД, DDL) SQL. Частина 1“.
П.1. Виберіть з бази даних напрямки рейсів та класи, на які ще не продано жодного квитка.
Розв’язання.
SELECT DISTINCT V.destination, C.name FROM voyage V, class C WHERE C.voyage=V.id_voyage AND C.id_class NOT IN
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
102 |
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
|
|
|
|
(SELECT class FROM ticket); |
|
Результуюча таблиця. |
|
|
|
|
|
|
|
|
Destination |
name |
|
|
Одеса – Бухарест |
бізнес |
|
|
Одеса – Бухарест |
економ |
|
|
Одеса – Бухарест |
економ покращений |
|
|
Одеса – Нью-Йорк |
бізнес |
|
|
Одеса – Нью-Йорк |
економ |
|
|
Одеса – Пекін |
бізнес |
|
|
Одеса – Пекін |
економ |
|
П.2. Виберіть з бази даних пункт призначення рейсу, дату вильоту та назву класу салону, на якій продано всі квитки.
Розв’язання.
SELECT |
V.destination, V.date_departure, C.name FROM |
voyage V, class C |
||
WHERE V.id_voyage=C.voyage AND C.quantity_place = |
|
|||
|
(SELECT COUNT(class) FROM ticket T |
|
||
|
WHERE C.id_class=T.class GROUP BY class); |
|||
Результуюча таблиця. |
|
|
|
|
|
|
|
|
|
destination |
|
date_departure |
|
name |
Одеса – Нью-Йорк |
2012-08-09 |
|
економ покращений |
|
П.3. Виберіть з бази даних напрямок рейсу, клас та кількість квитків, що залишилися у продажу. Результат відсортуйте за напрямком рейсу.
Розв’язання.
WITH count_ticket AS
(SELECT class, COUNT(id_ticket) AS kolvo FROM ticket GROUP BY class), count_place AS
(SELECT c.id_class, c.name, v.destination, quantity_place FROM class c, voyage v
WHERE c.voyage=v.id_voyage)
SELECT c.destination, c.name, quantity_place-kolvo AS tail FROM count_place c, count_ticket K
WHERE c.id_class=k.class ORDER BY c.destination;
Результуюча таблиця.
destination |
name |
tail |
Одеса – Лондон |
бізнес |
49 |
Одеса – Лондон |
економ покращений |
49 |
Одеса – Лондон |
економ |
99 |
Одеса – Нью-Йорк |
економ покращений |
46 |
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
103 |
|
|
МВД (DDL) SQL. Частина 2
Тепер повернемося до МВД SQL і розглянемо, по-перше, ряд аспектів, пов’язаних із впливом команд ММД, а по-друге, ще кілька елементів МВД, заснованих на команді SELECT і, у свою чергу, використовуваних у командах ММД.
Представлення, які модифікуються
Для початку розглянемо відновлення і введення інформації за допомогою представлень. Ми відзначали, що будь-які зміни, виконані над даними в представленні, будуть негайно відбиті в базовій таблиці цього представлення. При цьому необхідними умовами модифікації і виводу значень через представлення є такі:
1.Представлення не повинне містити функцій агрегатування.
2.Представлення не повинне використовувати оператори GROUP BY і HAVING у своєму визначенні.
3.Для забезпечення можливості введення значень представлення повинне включати всі поля базової таблиці, для яких визначене обмеження NOT NULL.
Наприклад. Представлення
CREATE VIEW |
AveRat AS |
|
SELECT |
Kod, AVG(Mark) FROM Rating |
|
GROUP BY |
Kod; |
|
не є обновлюваним. Чому? Для відповіді див. умови модифікації. |
||
А в представленні |
|
|
CREATE VIEW |
FIO |
AS |
SELECT |
Kod, SecondName, FirstName, Patronymic FROM Student; |
|
можна модифікувати ПІБ, але не можна вводити нові кортежі, тому що ряд полів мають обмеження на NULL-значення і не мають значень за замовчуванням.
Представлення ж
CREATE VIEW |
BadRat AS |
SELECT Kod, DKod, Mark, MDate FROM Rating |
|
WHERE |
Mark = 0; |
є обновлюваним. Тобто за допомогою нього в базову таблицю можна і вводити, й модифікувати значення. Однак тут можлива й така ситуація: команда
INSERT INTO BadRat VALUES(15,5,45, ‘25.12.2011’);
буде прийнята як коректна, і додасть кортеж у таблицю Rating. Однак же побачити результат цієї операції, ні, тим більше, його видалити користувач не зможе, тому що нове значення не відповідає умові вибірки. Уникнути такої ситуації можна шляхом додавання у визначення представлення інструкції:
…WITH CHECK OPTION;
Ця інструкція працює за принципом „все або нічого“ і блокує всі команди відновлення, результати яких не можуть бути відображені в представленні. Відповідно, команда INSERT з нашого прикладу буде відхилена.
Збережені процедури (ЗП)
Збереженою процедурою називається скомпільована програма довільної довжини,
написана мовою SQL, що зберігається в БД разом з іншими об’єктами.
Збережені процедури дозволяють скоротити кількість повідомлень чи транзакцій між клієнтом і сервером. Крім того, використання збережених процедур має ще ряд переваг:
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
104 |
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
|
|
1.Універсальність:
одна збережена процедура може використовуватися спільно багатьма клієнтами, створеними за допомогою різних мов програмування.
2.Ефективність:
зменшення навантаження на мережу каналу зв’язку між клієнтом і вузлом-сервером, тому що обробка записів виконується безпосередньо на сервері;
зменшення навантаження на вузол-сервер, тому що окремі етапи оптимізації коду процедури можуть здійснюватися не під час виконання процедури, а під час її реєстрації в СУБД.
3.Безпека:
користувачу можна надати можливість викликати збережену процедуру, але не керувати даними, що викликаються цією процедурою;
такі процедури можуть використовуватись для приховування від користувача багатьох особливостей конкретної будови системи чи БД, що забезпечує більший ступінь
незалежності і цілісності даних.
Існує 2 типи збережених процедур: процедури вибору і виконувані процедури. Відрі-
зняються вони тим, що процедури вибору обов’язково повинні повертати значення до викликаючої програми, а виконувані — можуть і не повертати значення.
Збережені процедури створюються за допомогою команди
CREATE PROCEDURE процедура
і складаються з заголовка процедури й тіла процедури. Заголовок процедури містить:
ім’я збереженої процедури, яке повинне бути унікальним серед імен процедур і таблиць у БД;
необов’язковий список вхідних параметрів і їхніх типів даних, значення яких процедура одержує від викликаючої програми;
оператор RETURNS зі списком вихідних параметрів і їхніх типів даних, у тому випадку, якщо процедура повертає значення джерелу виклику.
Завдяки цьому збережені процедури можуть використовуватись як табличні вирази в команді SELECT (замість відношення).
Тіло процедури складається з:
необов’язкового списку локальних змінних із вказівкою типів даних;
блока інструкцій, вкладеного між операторами BEGIN і END (не у всіх СУБД). Більшість СУБД і стандарт SQL підтримують багаторівневе вкладення блоків.
Мова збережених процедур і тригерів SQL містить:
•команди ММД SQL: INSERT, UPDATE, DELETE і SELECT;
•оператори і вирази SQL;
•розширення SQL, що включають інструкції присвоєння, управління потоками, реєстрації подій і обробки помилок, а саме:
змінна = вираз — операція присвоєння значення виразу локальній змінній, вхідному або вихідному параметру;
INTO список змінних — присвоєння змінним або параметрам результату роботи ко-
манди SELECT;
SUSPEND — повертає вихідні параметри викликаючій програмі і припиняє збережену процедуру доти, поки викликаюча програма не зажадає наступний кортеж. Не рекоме-
ндується використовувати у виконуваних процедурах;
FOR SELECT-вираз DO складений_оператор —
складений_оператор — інструкція або блок інструкцій, який буде виконаний для кожного рядка, повернутого SELECT-виразом, де SELECT-вираз — звичайна команда SELECT, за винятком того, що наприкінці команди має обов’язково бути присутнім
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
105 |
|
|
оператор INTO;
IF(умова) THEN складений_оператор [ELSE складений_оператор]
WHILE(умова) DO складений_оператор - цикл із передперевіркою;
EXCEPTION виняток — генерує пойменовану виняткову ситуацію виняток — визначену користувачем помилку, яка може бути оброблена оператором WHEN;
WHEN{помилка[, помилка[, …]] | ANY} DO складений_оператор — обробка помилок,
вказаних у списку, або будь-яких помилок, якщо вказано ANY. Ця інструкція, якщо є присутньою, вказується наприкінці збереженої процедури безпосередньо перед END;
EXIT — перехід на кінець збереженої процедури (останній END), наприклад, для переривання циклу;
EXECUTE PROCEDURE процедура [параметр[, параметр[, …]]] [RETURNING_VALUES [параметр[, параметр[, …]]] — виконує збережену процеду-
ру з ім’ям процедура, вхідними параметрами, переліченими після імені, і яка повертає значення в параметрах, перелічених після RETURNING_VALUES.
Вхідними і вихідними параметрами повинні бути змінні, визначені усередині поточної процедури. Завдяки цій інструкції можливі вкладені виклики процедур і рекурсії.
/* коментар */ — для коментарів.
Наприклад, процедура вибору, яка повертає інформацію про кожну групу: чисельність, мінімальний, середній і максимальний рейтинг з кожної дисципліни:
SET TERM ; |
^ |
|
|
CREATE PROCEDURE |
GroupInfo |
|
|
RETURNS |
(Spec |
CHAR(2), GNum |
INT, DName CHAR(30), |
|
NumOfStud INT, MinRat |
DEC, |
|
|
AveRat |
DEC, MaxRat |
DEC) |
AS |
|
|
BEGIN |
|
|
FOR |
SELECT S.Spec, GNum, DName, COUNT(S.Kod), |
|
|
MIN(Mark), AVG(Mark), MAX(Mark) |
|
|
FROM |
Student S, Rating R, Discipline D |
|
WHERE |
S.Kod = R.Kod AND D.DKod=R.Dkod |
|
GROUP BY S.Spec, GNum, DName |
|
|
INTO |
:Spec, :GNum, :DName, NumOfStud, |
DO |
|
:MinRat, :AveRat, :MaxRat |
SUSPEND; |
|
|
END^ |
|
|
|
|
|
SET TERM |
^ ; |
|
Значення команди SET TERM буде роз’яснено далі у розділі „Сценарії“. Поки що майте на увазі необхідність використання цих команд до та після команди CREATE PROCEDURE.
Як ми уже відзначали, використовувати таку збережену процедуру можна як таблич-
ний вираз в команді SELECT:
SELECT * FROM GroupInfo;
що дасть такий результат:
|
Spec |
GNum |
DName |
NumOfStud |
MinRat |
AveRat |
MaxRat |
|
|
АС |
954 |
Економіка |
1 |
97 |
97 |
97 |
|
|
ОІ |
943 |
Мережеві технології |
2 |
76 |
81 |
85 |
|
|
ОС |
102 |
Дослідження операцій |
1 |
100 |
100 |
100 |
|
|
ОМ |
971 |
Мережеві технології |
1 |
10 |
10 |
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
106 |
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
|
|
Spec |
GNum |
DName |
NumOfStud |
MinRat |
AveRat |
MaxRat |
ОС |
102 |
Технології проектування БД |
1 |
46 |
46 |
46 |
ОС |
102 |
Мережеві технології |
1 |
85 |
85 |
85 |
ОМ |
971 |
Технології проектування БД |
1 |
82 |
82 |
82 |
ОІ |
943 |
Дослідження операцій |
2 |
20 |
43 |
65 |
ОМ |
951 |
Технології проектування БД |
1 |
0 |
0 |
0 |
ОІ |
943 |
Технології проектування БД |
2 |
54 |
72 |
90 |
ОМ |
971 |
Дослідження операцій |
1 |
75 |
75 |
75 |
ОП |
971 |
Технології проектування БД |
1 |
86 |
86 |
86 |
ОП |
970 |
Економічна кібернетика |
1 |
30 |
30 |
30 |
Інший приклад використання збереженої процедури, якою можна скористатися в прикладі поділу групи:
SELECT Spec, MAX(GNum) FROM GroupInfo GROUP BY Spec;
Цей приклад демонструє, що над таблицею, яка повертається збереженою процедурою, можна виконувати всі операції вибірки SQL, у тому числі такі, що використовують агрегатні функції й угруповування.
Як було відзначено вище, у процедуру можна передавати параметри. Наприклад, процедура вибору, яка повертає коди студентів конкретної групи:
SET TERM |
; |
^ |
|
|
CREATE PROCEDURE |
StudGroup |
(Spec CHAR(2), GNum INT) |
||
RETURNS |
(Kod INT) |
|
||
AS |
|
|
|
|
BEGIN |
|
|
|
|
FOR |
SELECT |
Kod FROM |
Student |
|
|
|
WHERE Spec = :Spec AND GNum = :Gnum |
||
DO |
|
INTO |
:Kod |
|
SUSPEND; |
|
|
||
END^ |
|
|
||
|
|
|
|
|
SET TERM |
^ |
; |
|
|
Скористатися цією збереженою процедурою можна, задавши параметри в явному вигляді. Наприклад:
SELECT * FROM StudGroup(‘ОС’, 941);
Не менш ефективним буде виклик цієї збереженої процедури в підзапиті. Наприклад, для розв’язання попередньої задачі:
SELECT S.Spec, GNum, AVG(Mark) |
FROM Student S, Rating R |
WHERE R.Kod IN |
|
(SELECT Kod FROM |
StudGroup (S.Spec, S.GNum)) |
GROUP BY S.Spec, GNum;
Виконувані процедури, як видно з назви, повинні виконувати які-небудь дії. Наприклад, збережена процедура, яка видаляє усіх випускників з таблиці Student і їхній рейтинг із таб-
лиці Rating:
SET TERM ; ^
CREATE PROCEDURE RemoveDiploma (GNum INT) AS
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
107 |
||||||
|
|
|
|
|
|
|
|
DECLARE VARIABLE |
Kod |
INT; |
|
|
|
||
BEGIN |
|
|
|
|
|
|
|
FOR |
SELECT |
Kod |
FROM |
Student |
|
||
|
|
WHERE GNum = :Gnum |
|
|
|||
DO |
|
INTO |
:Kod |
|
|
|
|
BEGIN |
|
|
|
|
|
||
|
|
|
|
|
|
||
|
|
DELETE |
FROM |
Rating |
WHERE Kod = :Kod; |
|
|
|
END |
|
|
|
|
|
|
DELETE |
FROM |
Student WHERE |
GNum = :GNum; |
|
|||
END^ |
|
|
|
|
|
|
|
SET TERM |
^ |
; |
|
|
|
|
|
Тому що ця збережена процедура не повертає значення і, більш того, знищує при цьому кортежі, то використовувати її в команді SELECT не можна. Для виклику таких процедур використовується команда розширення SQL — EXECUTE PROCEDURE процедура.
EXECUTE PROCEDURE |
RemoveDiploma (961); |
Завдання.
1.Змінити процедуру для видалення всіх груп даного випуску.
2.Перемістити всі значення про таких студентів у спеціальну таблицю.
Особливості побудови збережених процедур в СУБД PostgreSQL
Мова програмування PLpg/SQL СУБД PostgreSQL
Більшість сучасних СУБД для програмування збережених процедур пропонує розширення стандарту SQL. СУБД Oracle була однією з перших промислових СУБД, що впровадила мову програмування PL/SQL не тільки як мову програмування процедур, але і як мову програмування додатків БД. По своїх можливостях PL/SQL можна порівнювати з більшістю алгоритмічних мов третього покоління (ANSI C, Pascal, Basic). СУБД PostgreSQL при створенні мови PLpg/SQL запозичила від СУБД Oracle більшість мовних конструкцій мови програмування PL/SQL.
Структура підпрограм PLpg/SQL
На відміну від збережених процедур стандартного SQL, наведених вище, та, навіть, на відміну від СУБД Oracle, яка містить два типи підпрограм — процедури (аналогічні стандартним) і функції, PLpg/SQL підтримує тільки користувальницькі функції.
Для створення такої функції використовується наступний синтаксис:
CREATE OR REPLACE FUNCTION Ім’я_функції
(Ім’я_параметра Вид_передачі_значення Тип_параметра, …) RETURN Тип_значення_яке_повертається
AS $$
PLpg/SQL програма, яка повинна завершуватися оператором
RETURN Значення_яке_повертається; $$ LANGUAGE plpgsql;
Можливі два види передачі значення в параметри функції:
IN — значення параметра передається у функцію (передача за значенням)
OUT — значення параметра може бути повернуте з функції (передача по посиланню) Розглянемо можливості мови PLpg/SQL для програмування збережених процедур. Аналогічно стандартному SQL структура збереженої процедури, яка створюється
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
108 |
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
|
|
PLpg/SQL, містить три блоки: декларативний блок, блок, який виконується, блок обробки винятків — умов, які викликають помилки або попередження про помилки:
DECLARE
// Оголошення
BEGIN
//Виконання команд обробки даних
EXCEPTION
//Обробка виняткових ситуацій
END;
Блок, який виконується, є обов’язковим, а два інших блоки можуть бути відсутніми. Проте важливою відмінністю діалекту PLpg/SQL від стандарту є те, що всі його функції
!належать тільки до категорії процедур вибору, а тому завжди повинні повертати значення. Внаслідок цього для виклику функцій в PLpg/SQL використовується тільки команда SELECT.
Змінні в PLpg/SQL
Змінна в PLpg/SQL може мати будь-який тип даних, властивий стандартному SQL, такий як NUMBER, CHAR, DATE, або властивий діалекту PLpg/SQL, такий як BOOLEAN. Наприклад, необхідно оголосити змінну з ім’ям Part_No так, щоб вона могла зберігати 4- хзначні числові значення, і змінну з ім’ям In_Stock, що може приймати булеве значення TRUE або FALSE. Оголошуються змінні цього прикладу так:
…Tax NUMBER(4), Bonus DEC(4, 2), Valid BOOLEAN…
Крім того, в PLpg/SQL є можливість оголошувати записи і таблиці, використовуючи складні типи даних цього діалекту: RECORD і TABLE.
Присвоєння значень змінним у цьому розширенні нічим не відрізняється від стандарту
SQL.
По-перше, це оператор присвоювання ‘:=‘. Наприклад: Tax := Price * Tax_Rate;
Bonus := Current_Salary * 0.10; Valid := FALSE.
По-друге, це введення в змінну значення з БД за допомогою фрази INTO команди SELECT або FETCH. Наприклад: обчислити 10% премії при виплаті зарплати співробітника:
SELECT Salary * 0.10 INTO Bonus FROM Lecturer;
Після цього значення змінної Bonus можна використовувати в інших обчисленнях, або внести його в таблицю БД.
Атрибути
Змінні в PLpg/SQL можуть бути так званими „атрибутами“, тобто властивостями, які дозволяють посилатися на тип даних, який має один зі стовпців таблиць БД, не повторюючи його оголошення. Синтаксис оголошення змінної як атрибута наступний:
Атрибут%TYPE
Наприклад, таблиця Books містить стовпець із ім’ям Title. Щоб дати змінній My_Title той же тип даних, що й у стовпця Title, не знаючи точного визначення цього стовпця в БД, досить указати наступну інструкцію:
…My_Title Books...Title%TYPE;…
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
109 |
|
|
Таке оголошення змінної має дві переваги:
―немає необхідності знати точний тип даних стовпця Title;
―якщо визначення стовпця Title у БД зміниться, наприклад, збільшиться його довжина, тип даних змінної My_Title зміниться відповідно під час виконання.
Також можна використовувати інший вид атрибута із синтаксисом:
Атрибут%ROWTYPE
ВPLpg/SQL для групування даних використовуються записи. Запис складається з декількох стовпців, у яких можуть зберігатися значення даних. Атрибут %ROWTYPE позначає тип запису, що представляє рядок у таблиці. Такий запис, тобто змінна, оголошена з атрибутом %ROWTYPE, може зберігати цілий рядок даних, отриманий з таблиці або через курсор (який буде розглянутий у наступному параграфі).
Стовпці в рядку таблиці та відповідні стовпці в запису мають однакові імена і типи даних. У наступному прикладі оголошується запис з ім’ям Dept_Rec:
…Dept_Rec Dept%ROWTYPE;…
Для звернення до значень стовпців запису використовуються уточнені посилання, як показує наступна інструкція:
My_DeptNo := Dept_Rec.DeptNo;
Управляючі структури
ВPLpg/SQL, як і в інших мовах програмування, існують команди передачі управління, до яких належать оператор умовного переходу і оператори циклів.
ВPLpg/SQL вони звуться управляючими структурами: умовного управління (IF- THEN-ELSE) і ітеративного управління FOR-LOOP, WHILE-LOOP.
Вякості прикладу умовного управління, розглянемо програму, яка підраховує кількість академічних заборгованостей студента, код якого дорівнює 5, та у відповідності з припустимою кількістю генерує для студента попереджуючі повідомлення. Оформимо цю програму у вигляді функції PLpg/SQL:
CREATE FUNCTION |
Попередження_if_else() |
|
|||
RETURNS |
INTEGER |
|
|
||
AS $$ |
|
|
|
|
|
DECLARE |
|
|
|
|
|
min_positive_mark |
CONSTANT |
NUMERIC(2) := 60; |
|||
max_negotive_mark_count CONSTANT |
NUMERIC(1) := 2; |
||||
negotive_mark_count |
NUMERIC(1); |
|
|||
StudentKod |
|
INTEGER; |
|
||
BEGIN |
|
|
|
|
|
StudentKod := 5; |
|
|
|
||
SELECT |
COUNT(R1.Kod) INTO negotive_mark_count |
||||
|
FROM |
Rating R1 |
|
||
|
WHERE |
Kod = StudentKod AND Mark < min_positive_mark; |
|||
IF |
negotive_mark_count > max_negotive_mark_count THEN |
||||
|
INSERT INTO |
Letters (kod, content) |
|
||
|
|
VALUES(StudentKod,'Ваша кількість заборгованостей =' || |
|||
|
|
|
negotive_mark_count || |
|
|
ELSE |
|
', що перевищує припустиму кількість!'); |
|||
|
|
|
|
||
|
INSERT INTO |
Letters (kod, content) |
|
||
|
|
VALUES(StudentKod, |
|
||
'Вам необхідно ліквідувати заборгованості у кількості ' ||
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
110 |
М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних |
|
|
negotive_mark_count);
END IF; RETURN 1;
END;$$ LANGUAGE 'plpgsql';
Для звернення до цієї функції треба виконати такий запит: SELECT Попередження_if_else();
Як було вже відзначено, в PostgreSQL всі функції повинні що-небудь повертати. Через те, що від цієї функції не очікується жодного результата, створюємо його штучно – повертаємо значення 1 як символ того, що функція успішно виконалася. Тобто при виклику за допомогою команди SELECT побачимо у результаті значення 1, а в таблиці Letters відповідні записи. Якщо в студента з кодом 5 взагалі немає оцінок або всі оцінки позитивні, додасться запис з кількістю заборгованостей, рівною 0.
Для циклу FOR-LOOP задається інтервал цілих чисел, а дії усередині циклу виконуються один раз для кожного цілого в цьому інтервалі. Наприклад: наступна програма визначає кількість академічних заборгованостей студентів з номерами від 1 до 7 та у відповідності з припустимою кількістю генерує для кожного студента повідомлення:
CREATE FUNCTION Попередження_for_loop() |
|
|||
RETURNS |
INTEGER |
|
|
|
AS $$ |
|
|
|
|
DECLARE |
|
|
|
|
min_positive_mark |
CONSTANT |
NUMERIC(2) := 60; |
||
max_negotive_mark_count CONSTANT |
NUMERIC(1) := 2; |
|||
negotive_mark_count |
NUMERIC(1); |
|
||
StudentKod |
|
Student.Kod%TYPE; |
||
Name |
|
|
Student.FirstName%TYPE; |
|
BEGIN |
|
|
|
|
FOR |
StudentKod IN 1..7 LOOP |
|
||
SELECT FirstName, COUNT(R.Kod) |
|
|||
|
INTO |
Name, negotive_mark_count |
||
|
FROM |
Student S, Rating R |
|
|
|
WHERE S.Kod = StudentKod AND |
|
||
|
|
Mark < min_positive_mark AND S.Kod = R.Kod |
||
|
GROUP BY FirstName; |
|
||
IF |
negotive_mark_count > max_negotive_mark_count THEN |
|||
|
INSERT INTO |
Letters (kod, content) |
||
VALUES(StudentKod, Name ||
'! Ваша кількість заборгованостей =' || negotive_mark_count ||
', що перевищує припустиму кількість!');
ELSE
INSERT INTO Letters (kod, content) VALUES(StudentKod, Name ||
'! Вам необхідно ліквідувати заборгованості у кількості '|| negotive_mark_count);
END IF;
END LOOP;
RETURN 1; END;$$ LANGUAGE 'plpgsql';
При виклику цієї функції за допомогою наступної інструкції:
Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет
