Модульні уроки (3/4)
Знайомство з тригерами
Тригер — це чарівний ящик (датчик), який автоматично запускає фрагмент логіки ДО або ПІСЛЯ події вставки, оновлення чи видалення в даних.\nОднак перед тим, як навчити таблицю реагувати, нам потрібно надати їй спеціальну «функцію тригера», написану на PL/pgSQL, яка має завершуватися поверненням синтетичного формату під назвою «TRIGGER».
Ці функції не приймають звичайні аргументи в дужках; натомість вони безкоштовно пропонують магічні вбудовані об’єкти NEW та OLD, які містять оригінальні або вхідні дані рядка з таблиці, яку спостерігає датчик!
CREATE OR REPLACE FUNCTION audit_deletions()
RETURNS TRIGGER AS $$
BEGIN
-- OLD.id is magically the id value of the poor record being deleted
INSERT INTO audit_log (table_name, record_id, action)
VALUES (TG_TABLE_NAME, OLD.id, 'DELETE');
RETURN OLD; -- Triggers before a Delete route must grant the exit
END;
$$ LANGUAGE plpgsql;Ця процедура виконує важку роботу із запису в журнал. Пізніше, на другому кроці, він буде постійно підключений до подій таблиці, яку ми хочемо захистити.
Спробуйте самі
Нам потрібно захистити клієнтів: нікого молодше 18 років (наша віртуальна перевірка) або, крім вигаданої логіки, ми хочемо змусити рядок «first_name», переданий під час INSERT, завжди зберігатися у верхньому регістрі в базі даних, ігноруючи будь-яке форматування клієнта JS.\nНапишіть функцію тригера під назвою «force_uppercase_name()». Він не приймає () аргументів.\nВін повертає TRIGGER. Створіть шаблон тіла.\nПримусово призначте весь вхідний об’єкт за допомогою магічного призначення «NEW.first_name = UPPER(NEW.first_name);». Потім ПОВЕРНІТЬ переформовану НОВУ змінну.
Показати підказку
СТВОРИТИ АБО ЗАМІНИТИ ФУНКЦІЮ force_uppercase_name() ПОВЕРТАЄ ТРИГЕР ЯК $$ BEGIN NEW.first_name = UPPER(NEW.first_name); ПОВЕРНУТИ НОВИЙ; КІНЕЦЬ; $$ LANGUAGE plpgsql;
Рішення доступне після 3 спроб
Створіть функцію тригера «protect_price_drops()», яка блокує шкідливі оновлення, якщо зловмисник збирається заощадити на смішно низьку ціну на продукті.\nВикористовуйте логіку на кшталт «IF NEW.unit_price < OLD.unit_price THEN», викликаючи власний виняток, який призводить до збою.\nФатальний виняток PL/pgSQL використовує форму «RAISE». ВИНЯТОК ''Prezzo non abbassabile!'';'.
Показати підказку
BEGIN IF NEW.unit_price < OLD.unit_price THEN RAISE EXCEPTION 'Prezzo non abbassabile!'; END IF; ПОВЕРНУТИ НОВИЙ; КІНЕЦЬ;
Рішення доступне після 3 спроб