Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Тригери | Деякі Додаткові Теми
Оптимізація SQL та Особливості Запитів

Тригери

Свайпніть щоб показати меню

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

DML-тригери

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

Типи DML-тригерів

  • After-тригери: ці тригери спрацьовують після виконання дії (вставка, оновлення, видалення) над таблицею;
  • Before-тригери: ці тригери спрацьовують до виконання дії. Вони дозволяють перехопити початкову дію та виконати власну логіку перед прийняттям рішення щодо подальшого виконання початкової дії.

Приклад after-тригера

Раніше ми розглядали приклад використання транзакції для додавання значень у таблиці BankAccounts та UserLogs як єдиної логічної одиниці у першому розділі цього курсу.
Тепер, замість використання транзакції, ми можемо досягти цього, створивши AFTER-тригер на операцію INSERT у таблиці BankAccounts.
У результаті ми зможемо додавати лише нові рахунки, а відповідне значення журналу буде автоматично додано тригером.

12345678910111213141516
-- Create an after-insert trigger for UserLogs CREATE FUNCTION after_insert_trigger_function() RETURNS TRIGGER AS $$ BEGIN -- Perform some action, like logging the insert INSERT INTO UserLogs (account_number, action) VALUES (NEW.account_number, CONCAT('New record inserted for ', NEW.account_holder)); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Attach the trigger to the BankAccounts table CREATE TRIGGER after_insert_trigger AFTER INSERT ON BankAccounts FOR EACH ROW EXECUTE PROCEDURE after_insert_trigger_function();
Опис запиту
expand arrow
  • Створення after insert-тригера для user_logs:

    • Створити функцію з назвою afterinserttriggerfunction().
    • Функція визначена для повернення тригера.
    • Тіло функції починається з блоку BEGIN.
    • Усередині блоку BEGIN виконується дія — вставка запису у таблицю userlogs.
    • Вставлений запис містить значення з нового рядка (NEW) події, що викликає тригер.
    • Вставлені значення включають accountnumber та конкатенований рядок із зазначенням дії.
    • Функція повертає новий рядок (NEW).
    • Функція написана мовою plpgsql.
  • Прив'язка тригера до таблиці bankaccounts:

    • Створюється тригер з назвою afterinserttrigger.
    • Тригер налаштований на виконання після операції INSERT у таблиці bankaccounts.
    • Тригер виконує функцію afterinserttriggerfunction для кожного зміненого рядка.
Note
Примітка

У тригерах PostgreSQL NEW — це спеціальна змінна-запис, яка представляє новий рядок, вставлений або оновлений у таблиці. Вона дозволяє отримувати доступ до значень стовпців нового рядка всередині функції тригера.
Якщо працюємо з видаленими рядками, потрібно використовувати змінну-запис OLD замість NEW.

Приклад тригера BEFORE

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

12345678910111213141516171819202122232425
-- Create the trigger function CREATE FUNCTION before_insert_trigger_function() RETURNS TRIGGER AS $$ BEGIN -- Check if the account balance is less than 0 IF (NEW.balance < 0) THEN -- If balance is less than 0, do nothing and return RAISE NOTICE 'Balance is less than 0. Action not logged.'; ELSE -- If balance is greater than or equal to 0, log the action RAISE NOTICE 'Logging insert into UserLogs'; -- Inserting into the UserLogs table INSERT INTO UserLogs (account_number, action) VALUES (NEW.account_number, CONCAT('Account created for ', NEW.account_holder)); END IF; -- Indicate that the trigger function has completed successfully RETURN NULL; END; $$ LANGUAGE plpgsql; -- Create the trigger CREATE TRIGGER before_insert_trigger BEFORE INSERT ON BankAccounts FOR EACH ROW EXECUTE PROCEDURE before_insert_trigger_function();
Опис запиту
expand arrow
  • Створення функції тригера:

    • Створити або замінити функцію з назвою before_insert_userlogs().
    • Функція визначена для повернення тригера.
    • Тіло функції починається з блоку BEGIN.
    • Усередині блоку BEGIN перевіряється умова, чи баланс рахунку менший за 0.
    • Якщо баланс менший за 0, виводиться повідомлення та дія не реєструється. Функція повертає NULL, щоб запобігти вставці.
    • Якщо баланс більший або дорівнює 0, виводиться повідомлення про реєстрацію дії.
    • Далі функція вставляє запис у таблицю userlogs, використовуючи значення з рядка NEW.
    • Вставлені значення включають accountnumber та конкатенований рядок, що вказує на дію.
    • Функція повертає NEW, дозволяючи виконати вставку.
    • Функція написана мовою plpgsql.
  • Створення тригера:

    • Створюється тригер з назвою before_insert_userlogs_trigger.
    • Тригер налаштований на виконання перед операцією INSERT у таблиці bankaccounts.
    • Тригер виконує функцію before_insert_userlogs() для кожного зміненого рядка.

Шаблон створення тригера

Можна спостерігати типовий шаблон створення тригерів: спочатку визначається функція для виконання певної логіки до або після операції. Далі цю функцію асоціюють як тригер із заданою таблицею та дією.

Зверніть увагу, що в операторі:

CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW
EXECUTE PROCEDURE proc_name;

є можливість використовувати UPDATE або DELETE замість операції INSERT.
Але зверніть увагу, що не можна створювати тригери для SELECT, оскільки оператор SELECT не змінює жодних рядків у таблиці!

question mark

Яка основна мета використання тригерів у базі даних?

Виберіть правильну відповідь

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 1

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Тригери

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

DML-тригери

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

Типи DML-тригерів

  • After-тригери: ці тригери спрацьовують після виконання дії (вставка, оновлення, видалення) над таблицею;
  • Before-тригери: ці тригери спрацьовують до виконання дії. Вони дозволяють перехопити початкову дію та виконати власну логіку перед прийняттям рішення щодо подальшого виконання початкової дії.

Приклад after-тригера

Раніше ми розглядали приклад використання транзакції для додавання значень у таблиці BankAccounts та UserLogs як єдиної логічної одиниці у першому розділі цього курсу.
Тепер, замість використання транзакції, ми можемо досягти цього, створивши AFTER-тригер на операцію INSERT у таблиці BankAccounts.
У результаті ми зможемо додавати лише нові рахунки, а відповідне значення журналу буде автоматично додано тригером.

12345678910111213141516
-- Create an after-insert trigger for UserLogs CREATE FUNCTION after_insert_trigger_function() RETURNS TRIGGER AS $$ BEGIN -- Perform some action, like logging the insert INSERT INTO UserLogs (account_number, action) VALUES (NEW.account_number, CONCAT('New record inserted for ', NEW.account_holder)); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Attach the trigger to the BankAccounts table CREATE TRIGGER after_insert_trigger AFTER INSERT ON BankAccounts FOR EACH ROW EXECUTE PROCEDURE after_insert_trigger_function();
Опис запиту
expand arrow
  • Створення after insert-тригера для user_logs:

    • Створити функцію з назвою afterinserttriggerfunction().
    • Функція визначена для повернення тригера.
    • Тіло функції починається з блоку BEGIN.
    • Усередині блоку BEGIN виконується дія — вставка запису у таблицю userlogs.
    • Вставлений запис містить значення з нового рядка (NEW) події, що викликає тригер.
    • Вставлені значення включають accountnumber та конкатенований рядок із зазначенням дії.
    • Функція повертає новий рядок (NEW).
    • Функція написана мовою plpgsql.
  • Прив'язка тригера до таблиці bankaccounts:

    • Створюється тригер з назвою afterinserttrigger.
    • Тригер налаштований на виконання після операції INSERT у таблиці bankaccounts.
    • Тригер виконує функцію afterinserttriggerfunction для кожного зміненого рядка.
Note
Примітка

У тригерах PostgreSQL NEW — це спеціальна змінна-запис, яка представляє новий рядок, вставлений або оновлений у таблиці. Вона дозволяє отримувати доступ до значень стовпців нового рядка всередині функції тригера.
Якщо працюємо з видаленими рядками, потрібно використовувати змінну-запис OLD замість NEW.

Приклад тригера BEFORE

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

12345678910111213141516171819202122232425
-- Create the trigger function CREATE FUNCTION before_insert_trigger_function() RETURNS TRIGGER AS $$ BEGIN -- Check if the account balance is less than 0 IF (NEW.balance < 0) THEN -- If balance is less than 0, do nothing and return RAISE NOTICE 'Balance is less than 0. Action not logged.'; ELSE -- If balance is greater than or equal to 0, log the action RAISE NOTICE 'Logging insert into UserLogs'; -- Inserting into the UserLogs table INSERT INTO UserLogs (account_number, action) VALUES (NEW.account_number, CONCAT('Account created for ', NEW.account_holder)); END IF; -- Indicate that the trigger function has completed successfully RETURN NULL; END; $$ LANGUAGE plpgsql; -- Create the trigger CREATE TRIGGER before_insert_trigger BEFORE INSERT ON BankAccounts FOR EACH ROW EXECUTE PROCEDURE before_insert_trigger_function();
Опис запиту
expand arrow
  • Створення функції тригера:

    • Створити або замінити функцію з назвою before_insert_userlogs().
    • Функція визначена для повернення тригера.
    • Тіло функції починається з блоку BEGIN.
    • Усередині блоку BEGIN перевіряється умова, чи баланс рахунку менший за 0.
    • Якщо баланс менший за 0, виводиться повідомлення та дія не реєструється. Функція повертає NULL, щоб запобігти вставці.
    • Якщо баланс більший або дорівнює 0, виводиться повідомлення про реєстрацію дії.
    • Далі функція вставляє запис у таблицю userlogs, використовуючи значення з рядка NEW.
    • Вставлені значення включають accountnumber та конкатенований рядок, що вказує на дію.
    • Функція повертає NEW, дозволяючи виконати вставку.
    • Функція написана мовою plpgsql.
  • Створення тригера:

    • Створюється тригер з назвою before_insert_userlogs_trigger.
    • Тригер налаштований на виконання перед операцією INSERT у таблиці bankaccounts.
    • Тригер виконує функцію before_insert_userlogs() для кожного зміненого рядка.

Шаблон створення тригера

Можна спостерігати типовий шаблон створення тригерів: спочатку визначається функція для виконання певної логіки до або після операції. Далі цю функцію асоціюють як тригер із заданою таблицею та дією.

Зверніть увагу, що в операторі:

CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW
EXECUTE PROCEDURE proc_name;

є можливість використовувати UPDATE або DELETE замість операції INSERT.
Але зверніть увагу, що не можна створювати тригери для SELECT, оскільки оператор SELECT не змінює жодних рядків у таблиці!

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 3. Розділ 1
some-alt