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

Konspekt_lektsiy_BD_amp_amp_SD

.pdf
Скачиваний:
28
Добавлен:
10.02.2016
Размер:
1.41 Mб
Скачать

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

111

 

 

SELECT Попередження_for_loop();

побачимо в її результаті 1, а в таблиці Letters — відповідні записи. Якщо у студента взагалі немає оцінок або всі вони позитивні, запис до таблиці Letters додасться, але без повідомлення (стовпець Content буде порожній).

Обробка помилок

В PLpg/SQL можна обробляти тільки внутрішні певні умови помилок, які називаються винятками. Коли виникає помилка, обробляється виняток. Це значить, що нормальне виконання припиняється, і управління передається в область обробки винятків або блоку підпрограми PLpg/SQL. Для обробки винятків створюються спеціальні програми — оброблювачі винятків.

Курсори

При відновленні і видаленні кортежів вибірка рядків з таблиці здійснювалася за первинним ключем або якоюсь умовою. Тобто вибиралася деяка множина (іноді одинична) кортежів із усієї таблиці. Однак часто виникає необхідність порядкового перегляду таблиці і відновлення або видалення поточного кортежу. Для розв’язання таких задач у SQL уведений ще один елемент МВД — курсор. Курсори дозволяють отримати доступ до окремих рядків

утаблиці.

УСУБД і, зокрема, в PostgreSQL існує два види курсорів: неявні і явні. PostgreSQL неявно оголошує курсор для будь-якої інструкції маніпулювання даними SQL, у тому числі для запиту, який повертає тільки один рядок. Більше того, для виконання речень SQL і збереження їхніх результатів СУБД PostgreSQL використовує „особисті областіSQL. Курсор цього діалекту SQL дозволяє звертатися до „особистої області“ по імені та одержувати з неї інформацію.

Існує 4 основних команди SQL, зв’язаних з курсорами: DECLARE X CURSOR, OPEN, FETCH, CLOSE.

Оператор DECLARE X CURSOR визначає курсор з ім’ям Х за допомогою оператора SELECT. Наприклад:

DECLARE cStudent CURSOR

FOR SELECT * FROM Student;

Причому на відміну від представлень, у цій інструкції не формується відношення для курсора. DECLARE CURSOR — це чисто декларативний (визначальний) вираз. Запит для курсора виконується тільки при відкритті курсора командою OPEN курсор. Наприклад:

OPEN cStudent;

Однак і ця інструкція тільки лише формує відношення в результаті запиту, але не відображає (не повертає) цей результат. Це відношення називається активною множиною.

Для вибірки єдиного кортежу з результуючої множини використовується команда FETCH. Наприклад:

FETCH cStudent;

Наступне виконання цієї команди буде повертати по одному чергові (наступні) рядки активної множини.

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

Діалект СУБД PostgreSQL підтримує двоспрямовані курсори. Для цього до команди FETCH додається опція напрям:

NEXT — наступний рядок (за замовчуванням),

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

112

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

PRIOR, FIRST, LAST — попередній, перший чи останній рядок,

ABSOLUTE крок, RELATIVE крок — перехід на визначений абсолютний або відносний крок у будь-якому напрямі.

Наприклад:

FETCH LAST FROM cStudent INTO x; FETCH RELATIVE -2 FROM cStudent INTO x;

де x — деяка локальна змінна чи параметр, в який записується результат.

До того ж в цьому діалекті введено команду MOVE, яка пересуває курсор у будь-якому напрямі, проте без отримання якихось даних. Тобто вона працює так само, як команда FETCH, за винятком того, що тільки пересуває курсор, не повертаючи рядок, до якого виконане переміщення.

Для розв’язання поставленої вище задачі видалення або відновлення поточного рядка в SQL існує два розширення:

1. Модифікуємий курсор, в оголошенні якого вказується операнд

FOR UPDATE OF список_атрибутів;

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

DECLARE cRating

CURSOR

FOR SELECT *

FROM Rating

FOR UPDATE OF

Mark;

2.Друге розширення — це так звані current-форми команд UPDATE і DELETE, які можна застосовувати до модифікуємого курсора, зазначеного в умові вибірки цих команд за допомогою оператора CURRENT OF курсор. Наприклад:

UPDATE Rating

SET Mark = 75

WHERE

CURRENT OF cRating;

або

DELETE FROM

Rating

WHERE

CURRENT OF cRating;

У більшості випадків, які вимагають явного курсору, СУБД PostgreSQL дозволяє використовувати курсорні цикли FOR замість операторів OPEN, FETCH і CLOSE, що спрощує програмування. Курсорний цикл FOR неявно повідомляє індекс свого циклу як запис %ROWTYPE, відкриває курсор, ітеративно витягує рядки даних з активної множини в стовпцях запису, і закриває курсор після того, як всі рядки оброблені. У наступному прикладі курсорний цикл FOR неявно оголошує запис Emp_Rec, як приналежний типу cEmp%ROWTYPE:

DECLARE Salary_Total INTEGER; CURSOR cEmp IS

SELECT SecondName, Salary, HireDate, DeptKod FROM Lecturer; BEGIN

FOR Emp_Rec IN cEmp LOOP

Salary_Total := Salary_Total + Emp_Rec.Salary; END LOOP;

END;

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

Якщо оголошується курсор, що отримує, скажемо, прізвище, зарплату, дату прийому та посаду співробітника, то PLpg/SQL дозволяє створити запис, що містить таку ж інформацію. Це також робиться за допомогою атрибута %ROWTYPE. Припустимо, що записане наступне

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

113

 

 

оголошення курсору та запису:

DECLARE CURSOR cEmp IS

SELECT SecondName, Salary, HireDate, Job FROM Lecturer; Emp_rec cEmp%ROWTYPE;

При виконанні інструкції

FETCH cEmp INTO Emp_rec;

значення стовпця SecondName таблиці Lecturer буде привласнено атрибуту SecondName запису Emp_rec, значення атрибута Salary буде привласнено атрибуту Salary.

Закриття курсора командою CLOSE приводить до звільнення використаних їм системних ресурсів. Наприклад:

CLOSE cRating;

На закінчення необхідно відзначити таке: більшість версій SQL не підтримує генерацію команд курсорів (звісно, окрім створення і видалення) у чистому виді. Тобто, не можна вводити і налагоджувати ці команди практично у всіх інтерактивних SQL-додатках. Ці команди і курсори цілком призначені для використання в рамках збережених процедур і тригерів — ще одного елемента мови даних SQL.

Тригери

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

Тригери — це підпрограми, написані SQL, які виконуються тоді, коли відбувається певна подія, спрямована до конкретної таблиці.

Такою подією може бути виконання якоїсь команди відновлення ММД SQL: вставки, відновлення або видалення даних. Відповідно кожен тригер асоціюється з конкретною операцією і конкретною таблицею. Така відповідність встановлюється при створенні тригера командою CREATE TRIGGER. Формат цієї команди в різних СУБД трохи відрізняється. Тому спочатку розглянемо побудову тригерів в стандартному SQL, а потім — особливості роботи з тригерами з використанням діалекту PostgreSQL.

Тригери можуть використовуватися в наступних областях функціонування додатків:

реалізація контролю за всіма діями користувачів БД;

забезпечення цілісності змісту БД;

реалізація складних правил роботи програм;

забезпечення складних правил безпеки даних;

автоматичне створення значень у полях таблиць БД.

Як приклад забезпечення цілісності розглянемо задачу видалення кортежів, що відно-

сяться до випускників вузу, із двох таблиць: Student і Rating. Ця задача розв’язувалась шляхом виклику виконуваної процедури, тому що було необхідно видалити спочатку кортежі з деталізованої таблиці, а потім — з базової. Розв’язання цієї задачі за допомогою тригерів буде виглядати таким чином:

CREATE TRIGGER

DelRating

FOR Student

ACTIVE BEFORE DELETE

 

AS BEGIN

 

 

DELETE

FROM

Rating R

WHERE

R.Kod = OLD.Kod;

END

 

 

Зверніть увагу, що цей тригер працює з таблицею Rating, проте „прив’язаний“ до таб- !лиці Student і направленої до неї події DELETE.

У результаті розв’язання поставленої задачі зведеться до єдиного (як і при збереженій

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

114

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

процедурі) запиту:

 

DELETE FROM Student WHERE

GNum = 941;

Завдання. Створити тригер для повного вирішення задачі видалення суцільних двієчників з розділу „Підзапити“.

У команді CREATE TRIGGER додався ще ряд інструкцій, характерних тільки для мови збережених процедур і тригерів:

Параметр

Опис

ACTIVE

необов’язковий оператор, який використовується за замовчуванням (тільки в

 

InterBase), призначений для активації тригера. За допомогою інструкції

 

ALTER TRIGGER INACTIVE у InterBase можна „відключити“ тригер, не

 

знищуючи його.

BEFORE

говорить про те, що тригер повинен бути активований перед виконанням ко-

 

манди, з яким пов’язаний тригер (INSERT, UPDATE або DELETE).

 

Протилежна їй інструкція — AFTER (активація після виконання операції).

OLD

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

 

яке було в кортежі перед виконанням операції UPDATE або DELETE.

 

Відповідно, контекстна змінна NEW дозволяє послатися на нове значення

 

стовпця при виконанні операції UPDATE або INSERT.

Наприклад:

CREATE TRIGGER AddNewRating FOR Student AFTER INSERT

AS BEGIN

INSERT INTO Rating (Kod) VALUES(NEW.Kod);

END

Цей тригер дозволяє при виконанні команди

INSERT INTO Student

VALUES( 20, ‘Ааа’, ‘Ббб’, NULL, 5, ‘ОІ’, 981, NULL, NULL);

автоматично додати кортеж у таблицю Rating з таким же значенням поля Kod та нульовим значенням рейтингу (значення за замовчуванням).

У СУБД PostgreSQL тригер складається із двох частин: тригерна подія, дії тригера. Тригерна подія описується у вигляді:

CREATE OR REPLACE TRIGGER Ім’я_тригера Тип_події Подія ON Ім’я_таблиці Область_застосування;

Параметр Тип_події (BEFORE або AFTER) і параметр Ім’я_таблиці (операції модифікації над якою перехоплюються тригером) нічим не відрізняються від використовуваних у стандартному SQL, як і параметр Подія, який визначає тип SQL-операції. Але в цьому діалекті при операції UPDATE можна вказувати ім’я атрибута таблиці, при впливі на який спрацьовує тригер.

Основною особливістю тригерної події PLpg/SQL є параметр Область_застосування, що може мати наступні значення:

FOR EACH ROW тригер спрацьовує стільки разів, скільки операція модифікації (UPDATE) впливає на записи таблиці (якщо при операції модифікації не був порушений жодний запис, то тригер не спрацює жодного разу);

FOR STATEMENT тригер спрацьовує лише один раз разом із самою операцією модифікації, навіть якщо операція модифікації не торкнулася жодного запису таблиці.

При використанні множинних подій, коли тригер може перехоплювати відразу кілька

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

115

 

 

типів подій (INSERT, UPDATE, DELETE) у підпрограму PLpg/SQL необхідно включити сис-

темні логічні змінні INSERTING, UPDATING, DELETING, які мають тип даних BOOLEAN (TRUE, FALSE) і повертають TRUE, якщо тригер спрацював при операції INSERT, UPDATE, DELETE відповідно.

Дії тригера — це збережена процедура у вигляді функції (FUNCTION), яка виконується при спрацьовуванні тригера і повертає значення типу TRIGGER. Якщо процедура спроектована з використанням мови PLpg/SQL, то, крім стандартних контекстних змінних NEW. і OLD., можна також використовувати наступні системні змінні:

TG_NAME

ім’я тригера, який виконується;

TG_WHEN

значення параметра Тип_події з тригерної події;

TG_LEVEL

значення параметра Область_застосування з тригерної події;

TG_OP

тип операції модифікації, яка перехоплена тригером;

TG_RELNAME

ім’я таблиці, над якою виконується операція модифікації;

TG_NARGS

кількість параметрів збереженої процедури, яка входить у дії тригера;

TG_ARGV[]

масив значень параметрів збереженої процедури (індекс починається з

 

0).

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

Приведемо приклад. Нехай у БД існує таблиця Employer зі структурою:

CREATE TABLE

Employer

(Emp_Num

INTEGER,

Name

CHAR(40),

Job

CHAR(20),

Tax

NUMERIC(4,2));

Необхідно відслідковувати зміни над таблицею Employer через збереження їх у таблицю Audit_Employer, структура якої може мати вигляд:

CREATE TABLE

Audit_Employer

(Emp_Num

INTEGER,

Name

CHAR(40),

Job

CHAR(20),

Tax

NUMERIC(4,2),

Oper_type

CHAR(1),

User_Name

CHAR(20),

Change_time

TIMESTAMP);

Для цього створимо тригер, який перехоплює всі операції модифікації над таблицею

Employer і вносить їх у таблицю Audit_Employer.

Опис тригерної події та дій тригера представлено нижче.

CREATE OR REPLACE FUNCTION Audit_Employer_F() RETURNS TRIGGER AS $$

BEGIN

IF (Tg_op =‘INSERT’ OR Tg_op =‘UPDATE’) THEN INSERT INTO Audit_Employer VALUES

(NEW.Name, NEW.Job, NEW.Tax, SUBSTR(Tg_op,1,1), CURRENT_USER, CURRENT_TIME);

RETURN NEW; ELSE

INSERT INTO Audit_Employer VALUES

(OLD.Name, OLD.Job, OLD.Tax, SUBSTR(Tg_op,1,1), CURRENT_USER, CURRENT_TIME);

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

116

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

RETURN OLD; END IF;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER Audit_Employer

AFTER INSERT OR UPDATE OR DELETE ON Employer

FOR EACH ROW EXECUTE PROCEDURE Audit_Employer_F();

У представленому тригері застосовуються наступні системні функції: CURRENT_USER — ім’я користувача, який виконує операції; CURRENT_TIME — поточний час;

SUBSTR(Рядок, Початковий_номер, Кількість_символів) — це функція, що витягує з рядка підрядок, який починається з символу з номером (Початковий_номер + 1) і має довжину, що дорівнює значенню параметра Кількість_символів.

Тригери, які описуються конструкціями діалекту PLpg/SQL можуть забезпечувати більш складні правила цілісності, ніж це передбачено в стандарті.

Крім випадків, коли необхідна цілісність не забезпечується простими декларативними обмеженнями цілісності з використанням зовнішніх ключів (FOREIGN KEY), тригери PLpg/SQL використовуються, коли цілісність зв’язує таблиці, розташовані на різних вузлах розподіленої БД, або реалізують більш складні правила цілісності, ніж обмеження за значенням (CHECK-інструкція). Зокрема, тригер може виконати складний контроль за даними перед тим, як дозволити виконати деякі операції, перехоплені тригером.

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

У розв’язанні використовується додаткова таблиця-довідник Job_Classification з наступною структурою:

CREATE TABLE Job_Classification

(Job

CHAR(20) PRIMARY KEY,

Min_Tax

NUMERIC(4,2),

Max_Tax

NUMERIC(4,2));

Прикладом заповнення таблиці може бути наступне:

INSERT INTO

Job_Classification

VALUES (‘JOB1’,10,30);

INSERT INTO

Job_Classification

VALUES (‘JOB2’,20,60).

Опис тригера для розв’язання поставленої задачі виглядає таким чином:

CREATE OR REPLACE FUNCTION Tax_Check_F() RETURNS TRIGGER AS $$

DECLARE

Min_Tax Job_Classification.Min_Tax%TYPE;

Max_Tax Job_Classification.Max_Tax%TYPE; BEGIN

/* отримати мінімальний і максимальний оклад для нової посади службовця з таблиці Job_Classification в Min_Tax і Max_Tax */

SELECT Min_Tax, Max_Tax INTO Min_Tax, Max_Tax FROM Job_Classification WHERE Job = NEW.Job;

/* якщо новий оклад службовця менше або більше, ніж обмеження за посадовою класифікацією, виконується виняткова ситуація, а операція скасовується. */

IF (NEW.Tax < Min_Tax OR NEW.Tax > Max_Tax) THEN RAISE EXCEPTION

‘Оклад службовця % поза межами діапазону’, NEW.Tax;

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

117

 

 

END IF; RETURN NEW;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER Tax_Check BEFORE INSERT OR UPDATE ON Employer FOR EACH ROW EXECUTE PROCEDURE Tax_Check_F();

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

дні дні. Розв’язання:

CREATE OR REPLACE FUNCTION Repmit_Changes_F() RETURNS TRIGGER AS $$

BEGIN

/* перевірка для вихідних днів */

IF (TO_CHAR(CURRENT_DATE,’DY’)= ‘SAT’ OR TO_CHAR(CURRENT_DATE,’DY’)= ‘SUN’)

THEN RAISE EXCEPTION ‘У вихідні працювати не можна’; END IF;

/* перевірка за години роботи (з 8 до 18) */

IF (TO_CHAR(CURRENT_DATE,’HH24’) < 8 OR TO_CHAR(CURRENT_DATE,’HH24’) > 18)

THEN RAISE EXCEPTION ‘Зараз працювати не можна’; END IF;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER Emp_Repmit_Changes

BEFORE INSERT OR UPDATE OR DELETE ON Employer FOR Statement EXECUTE PROCEDURE Repmit_Changes_F();

Функція TO_CHAR(CURRENT_DATE,’HH24’) одержує з поточної дати поточний час. Функція TO_CHAR(CURRENT_DATE,’DY’) одержує з поточної дати день тижня. Якщо в БД PostgreSQL використовується російська локалізація, то функція повертає абревіатуру назв днів тижня російською мовою (ПНД, ВТР ..., СБТ). Для перевірки значень можна виконати запит:

SELECT TO_CHAR(CURRENT_DATE,’DY’) FROM EMPLOYER;

Функція TO_CHAR(CURRENT_DATE,’DD’) отримує з поточної дати значення дня.

Підтримка сховищ даних засобами PLpg/SQL.

Основна мета створення сховищ даних — прискорити або оптимізувати обробку великих обсягів інформації. В PLpg/SQL для підтримки таких структур використовуються такі елементи МВД цього діалекту SQL, як тригери і матеріалізовані представлення.

Як відзначалося раніше (див. п. „Представлення“ с. 65) матеріалізовані представлення відрізняються від стандартних для SQL віртуальних представлень (або просто представлень) тим, що зберігаються в БД у явному (фізичному або матеріалізованому) вигляді, тоді як віртуальне представлення зберігає тільки SQL-запит, який описує бажану форму подання БД для користувача. Матеріалізоване представлення — це реальна таблиця БД, сформована та заповнена на підставі SQL-запиту.

Для підтримки матеріалізованих представлень необхідно пройти два етапи:

створити таблиці на підставі SQL-запиту;

забезпечити узгодження вмісту таблиць, які входять до SQL-запиту, і вмісту матеріалі-

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

118

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

 

 

зованого представлення.

Розглянемо приклад створення матеріалізованого представлення, яке зберігає результати наступного SQL-запиту:

SELECT Job, COUNT(Job) FROM Lecturer GROUP BY Job;

Для створення таблиці з матеріалізованим представленням, ім’я якої Report, необхідно виконати запит:

CREATE TABLE Report AS

SELECT Job, COUNT(Job) FROM Lecturer GROUP BY Job;

Нижче представлений тригер, який забезпечує асинхронне узгодження вмісту таблиці

Lecturer:

CREATE OR REPLACE FUNCTION Report() RETURNS TRIGGER AS $$

BEGIN

IF Tg_op = ‘INSERT’ THEN

SELECT COUNT(*) FROM Report WHERE Job = NEW.Job; IF FOUND THEN

UPDATE Report SET Count = Count + 1 WHERE Job = NEW.Job;

ELSE

INSERT INTO Report VALUES(NEW.Job, 1); END IF;

END IF;

IF Tg_op = ‘UPDATE’ AND NEW.Job != OLD.Job THEN UPDATE Report SET Count = Count + 1

WHERE Job = NEW.Job; UPDATE Report SET Count = Count - 1

WHERE Job = OLD.Job;

END IF;

IF Tg_op = ‘DELETE’ THEN

UPDATE Report SET Count = Count - 1 WHERE Job = OLD.Job;

END IF;

IF Tg_op = ‘INSERT’ OR Tg_op = ‘UPDATE’ THEN RETURN NEW;

ELSE RETURN OLD; END IF;

END;

$$ LANGUAGE plpgsql;

CREATE TRIGGER Report AFTER INSERT OR UPDATE OR DELETE ON Lecturer FOR EACH ROW EXECUTE PROCEDURE Report();

Демонстраційний приклад

Запишіть SQL-запити для маніпулювання даними з таблиць, що створені у завданні „Демонстраційний приклад“ розд. „Мова визначення даних (МВД, DDL) SQL. Частина 1“.

П.1. Створіть тригер, який при додаванні нового рейсу внесе дані до зв’язаних(-ої) таб- лиць(-і).

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

119

 

 

 

Розв’язання.

 

CREATE FUNCTION voyage_class()

 

RETURNS trigger

 

AS

BEGIN

 

 

INSERT INTO class (voyage) VALUES (new.id_voyage);

 

 

RETURN new;

 

 

END;'

 

LANGUAGE 'plpgsql';

 

CREATE TRIGGER voyage_class

 

AFTER INSERT ON voyage

 

FOR EACH ROW

 

EXECUTE PROCEDURE voyage_class();

 

П.2. Створіть тригер, для видалення співробітника, якого звільнили

 

Розв’язання.

 

CREATE FUNCTION del_employee()

 

RETURNS trigger

 

AS

BEGIN

 

 

UPDATE ticket SET employee=NULLЇ

 

WHERE employee=old.id_employee;

RETURN old;

END;'

LANGUAGE 'plpgsql';

CREATE TRIGGER del_employee

BEFORE DELETE ON employee

FOR EACH ROW

EXECUTE PROCEDURE del_employee();

П.3. Створіть функцію, яка буде при видачі квитка вносити дані в таблиці Passenger та Ticket, при цьому перевіряти чи існує співробітник, який видає квиток, та клас салону, на якій видають квиток, при помилці повинні бути відображені відповідні повідомлення.

Розв’язання.

CREATE OR REPLACE FUNCTION ticket_create -- назва функції

(full_name_pas CHAR (30), sex CHAR (1), passport CHAR, name_class CHAR (30), place INT, full_name_emp CHAR(30), operation CHAR(7))

RETURNS INTEGER -- функція повертає тип даних integer

AS $$

--Початок тіла функції

--Секція об’яви змінних.

DECLARE

id_passenger passenger.id_passenger%TYPE; -- тип даних посилається на тип даних поля id_passenger таблиці passenger

id_ticket ticket.id_ticket%TYPE; t_class class.id_class%TYPE;

t_employee employee.id_employee%TYPE;

--Секція тіла функції.

BEGIN

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

120М. Г. Глава. Технологія проектування і адміністрування баз даних та сховищ даних

--Отримання нового значення коду пасажира з генератора "s_passenger" id_passenger := NEXTVAL('s_passenger');

-- Додавання запису до таблиці

INSERT INTO passenger VALUES (id_passenger,full_name_pas,sex,passport);

--Отримання нового значення коду квитка з генератора "s_ticket" id_ticket := NEXTVAL('s_ticket');

--Перевірка на правильність значення вхідного параметру класу

--з таблиці "class" через отримання відповіді на запит.

--Результат запиту відправляється в змінну t_class (код класу).

SELECT id_class INTO t_class FROM class WHERE name = name_class;

--Якщо відповідь пуста, то значення класу некоректне.

IF NOT FOUND THEN

--Виклик обробника помилки та виведення на екран повідомлення.

--В рядку з повідомленням параметр % вказує на

--значення змінної після коми.

RAISE EXCEPTION 'Помилка: Класу % не існує', name_class;

END IF;

SELECT id_employee INTO t_employee FROM employee WHERE full_name = full_name_emp;

--Якщо відповідь пуста, то значення співробітника некоректне.

IF NOT FOUND THEN

--Виклик обробника помилки та виведення на екран повідомлення.

--В рядку з повідомленням параметр % вказує на

--значення змінної після коми.

RAISE EXCEPTION

'Помилка: Співробітника % не існує', full_name_emp;

END IF;

--Додавання запису до таблиці

INSERT INTO ticket

VALUES (id_ticket, id_passenger, t_class, place, t_employee, operation);

--Виведення на екран повідомлення про успішну видачу квитка

RAISE NOTICE 'Квиток видано';

--Повернення з функції значення коду квитка

RETURN id_ticket;

END;

-- Завершення тіла функції

$$ LANGUAGE plpgsql; -- назва модуля обробки мовних конструкцій тіла функції

Приклад виклику функції видачі квитка:

SELECT Ticket_Create ('Іванов','м','КМ 897654','бізнес',12,'Арсірій О.О.','покупка');

І, нарешті, перевірка результату: SELECT * FROM Passenger;

Кафедра економічної кібернетики та інформаційних технологій. Одеський національний політехнічний університет

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