Тригери
Накратко: Тригерът е набор от заявки, които базата пуска сама при INSERT, UPDATE или DELETE в таблица, например за дневник на цените или за наличността.
Проблем
Кой смени цената?
Клиент се оплаква, че вчера кафето е струвало по-малко. В базата има само днешната цена. Кога е сменена и от колко? Няма откъде да се разбере.
Можеш да накараш всяка програма, която пипа цените, да пише и в дневник. Но някой ще забрави: скрипт за поскъпване, ръчна поправка, нова програма след година.
Идеята
Тригер
Тригерът е заявка, която базата пуска сама, когато нещо се промени в таблица. Пише се веднъж и важи за всеки, който пише в базата.
AFTER UPDATE OF price ON products: след всяка промяна на цената.WHEN OLD.price <> NEW.price: само ако цената наистина е различна.OLDе редът преди промяната,NEWслед нея.- Между
BEGINиENDса заявките на тригера. Тук не значат транзакция, а тялото му.
Двете промени на цената са в дневника, без програмата да знае за него.
Виж го
Наличността сама
Тригер може и да поддържа данни: всеки нов ред в поръчка намалява наличността на продукта.
Ябълките са били 80, сега са 77. Тригерът работи в същата транзакция като INSERT. Ако поръчката се върне с ROLLBACK, връща се и наличността.
Пробвай
Сигнал за лош отзив
Таблицата alerts (review_id, product_id) вече я има. Напиши тригер, който при нов отзив с оценка 1 записва в alerts номера на отзива и продукта. Проверката добавя два отзива, с оценка 1 и 5, и гледа alerts.
Решение
CREATE TRIGGER bad_review
AFTER INSERT ON reviews
WHEN NEW.rating = 1
BEGIN
INSERT INTO alerts VALUES (NEW.id, NEW.product_id);
END;CREATE TRIGGER bad_reviewAFTER INSERT ON reviewsWHEN NEW.rating = 1BEGIN INSERT INTO alerts VALUES (NEW.id, NEW.product_id);END;В alerts влиза само отзивът с оценка 1.
Идеята
Кога да, кога не
Тригерите са добри за неща, които трябва да станат винаги, каквато и програма да пише: дневник на промените, поддържане на изчислена колона, проверка, която CHECK не може да направи.
Цената им: логиката е скрита. Който чете кода на програмата, вижда един INSERT, а базата прави още три неща. Тригер, който пуска тригер, който пуска тригер, се отстранява трудно. Бизнес правила като отстъпки и промоции обикновено са по-ясни в кода на програмата.
По-точно, за любопитните
В PostgreSQL тялото на тригера е отделна функция (CREATE FUNCTION … RETURNS trigger, после CREATE TRIGGER … EXECUTE FUNCTION). Има и BEFORE тригери, които могат да променят NEW, преди редът да влезе. SQLite има и BEFORE, и INSTEAD OF за изгледи.
Тест