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

Лабораторная работа №2 БД-1

.pdf
Скачиваний:
0
Добавлен:
07.01.2025
Размер:
1.83 Mб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

ИНСТИТУТ НЕПРЕРЫВНОГО И ДИСТАНЦИОННОГО ОБРАЗОВАНИЯ

КАФЕДРА ПРИКЛАДНОЙ ИНФОРМАТИКИ

ОЦЕНКА

 

 

ПРЕПОДАВАТЕЛЬ

 

 

канд. техн. наук, доцент

подпись, дата

Е. Л. Турнецкая

должность, уч. степень, звание

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ

Лабораторная работа №2. Программная реализация триггеров

по дисциплине: Базы данных

РАБОТУ ВЫПОЛНИЛ

 

 

 

 

 

СТУДЕНТ гр. №

Z1411

 

 

Я. Н. Тюттерин

 

номер группы

 

подпись, дата

 

инициалы, фамилия

Студенческий билет №

2022 / 4886

 

 

 

 

 

 

 

 

Санкт-Петербург 2024

Лабораторная работа № 2. Программная реализация триггеров

Цель работы: получение практических навыков по программной реализации триггеров на сервере PostgreSQL.

Для начала поставим цель. Предположим, что в БД нет возможности производить удаление связанных записей при удалении родительской. То есть отсутствует функционал вида REFERENCES ON DELETE CASCADE. В связи с этим требуется необходим триггер, который будет удалять записи из связующей таблицы, иначе БД не позволит удалить записи из родительской таблицы.

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

Для начала потребуется функция, которая будет вызываться из триггера при удалении записи из таблицы с достижениями. Ее листинг представлен ниже.

CREATE OR REPLACE FUNCTION delete_from_achievement_worker() RETURNS TRIGGER

AS $$

begin

delete from achievement_worker where achievement_id = old.id;

RETURN old;

END;

$$ LANGUAGE plpgsql;

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

CREATE TRIGGER before_delete_achievements

BEFORE DELETE ON achievements

FOR EACH ROW

EXECUTE FUNCTION delete_from_achievement_worker();

Содержимое связующей таблицы достижений и работников представлено на рисунке 1.

Рисунок 1 - Содержимое связующей таблицы

Выполним запрос delete from achievements where id = 6; В результате получили результат, представленный на рисунке 2.

Рисунок 2 - Результат выполнения запроса с исполнением триггера на удаление

Теперь начнем работу над INSERT-триггером. Например, нам потребовалось сделать так, чтобы при добавлении нового работнику в нашу систему и, если его возраст меньше 25, то ему сразу же добавляется достижение - “Молодой специалист”.

Для начала необходимо завести функцию, которая будет вызываться в триггере. Содержимое таблицы с достижениями представлено на рисунке 3.

Рисунок 3 - Содержимое таблицы достижений

Листинг функции представлен ниже:

CREATE OR REPLACE FUNCTION add_achievent_for_young_specialist() RETURNS TRIGGER

AS $$

begin

insert into achievement_worker(achievement_id, worker_id) values (7, new.id);

RETURN old;

END;

$$ LANGUAGE plpgsql;

Теперь создадим триггер, который будет вызывать эту функцию. Используется AFTER, так как на этапе вставки в связующую таблицу - значение идентификатора создаваемое пользователя уже должно быть известно. Листинг представлен ниже:

CREATE TRIGGER trigger_add_achievent_for_young_specialist after insert ON workers

for each row

when ((DATE_PART('year', CURRENT_DATE) - DATE_PART('year', new.date_of_birth)) <= 25)

EXECUTE FUNCTION add_achievent_for_young_specialist();

Содержимое связующей таблицы до вставки нового работника представлено на рисунке 4.

Рисунок 4 - Содержимое связующей таблицы до вставки

Выполним запрос INSERT INTO workers(first_name, last_name, patronymic, gender, salary,

date_of_birth) VALUES ('Tyutterin', 'Yakov', 'Nikolaevich', 'M', 100000, '2001-08-06');. Содержимое связующей таблицы после вставки представлено на рисунке 5.

Рисунок 5 - Содержимое связующей таблицы после вставки

При попытке добавить работника с большим возрастом - достижение не будет добавлено. Выполним INSERT INTO workers(first_name, last_name, patronymic, gender, salary,

date_of_birth) VALUES ('Zotov', 'Mikhail', 'Urievich', 'M', 110000, '1978-01-20');. Результаты

представлены на рисунках 6-7.

Рисунок 6 - Вставка новой записи

Рисунок 7 - Содержимое связующей таблицы

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

Для начала необходимо добавить эту колонку в таблицу работников. Для этого необходимо выполнить:

alter table workers add column active boolean default true;

alter table workers alter column active set not null;

Теперь можно приступить к написанию функции для триггера. Ее листинг представлен ниже:

CREATE OR REPLACE FUNCTION delete_achievents_and_positions_on_deactivation_worker()

RETURNS TRIGGER AS $$ begin

delete from achievement_worker where worker_id = old.id; delete from position_worker where worker_id = old.id;

RETURN old;

END;

$$ LANGUAGE plpgsql;

Листинг создания триггера представлен ниже:

CREATE TRIGGER trigger_on_deactivation_worker

before update ON workers

for each row

when (old.active != new.active and new.active = false)

EXECUTE FUNCTION delete_achievents_and_positions_on_deactivation_worker();

Рисунок 8 - Содержимое связующей таблицы достижений

Рисунок 9 - Содержимое связующей таблицы позиций

Выполним запрос для деактивации работника с идентификатором 3, update workers set active = false where id = 3;. Результаты выполнения триггера представлены на рисунках

10-11.

Рисунок 10 - Содержимое после выполнения триггера

Рисунок 11 - Содержимое после выполнения триггера

Вывод

В результате проделанной работы были изучены различные варианты создания триггеров. Разобраны и опробованы варианты BEFORE и AFTER для исполнения триггера до и после выполнения запроса.

Список использованных источников

1)Методические указания по выполнению лабораторной работы: https://pro.guap.ru/inside/student/tasks/314b0b1fbbcd44ddc3b8eb6f373fd950/download

2)Документаци по триггерам в PostgreSQL: https://www.postgresql.org/docs/current/sql-createtrigger.html

3)Документация по работе с функциями в PostgreSQL: https://www.postgresql.org/docs/current/sql-createfunction.html

4)Документация по PostgreSQL: https://www.postgresql.org/docs/current/ddl-alter.html