Lecții din modul (3/4)
Introducere în declanșatoare
Un declanșator este o cutie magică (un senzor) care rulează automat o bucată de logică ÎNAINTE sau DUPĂ un eveniment de inserare, actualizare sau ștergere în date.\nÎnainte de a învăța un tabel să reacționeze, trebuie să îi dăm o „Funcție de declanșare” specială scrisă în PL/pgSQL care trebuie să se termine prin returnarea unui format sintetic numit „TRIGGER”.
Aceste funcții nu acceptă argumente normale între paranteze; în schimb, oferă obiectele magice încorporate NEW și OLD gratuit, care conțin datele de rând originale sau primite din tabelul pe care îl urmărește senzorul!
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;Această procedură face munca grea de a scrie în jurnal. Ulterior, într-o a doua etapă, va fi conectat permanent la evenimentele mesei pe care dorim să o protejăm.
Încercați-l singur
Trebuie să protejăm clienții: nimeni sub 18 ani (verificarea noastră virtuală) sau, dincolo de logica fictivă, vrem să forțăm șirul „first_name” transmis la momentul INSERT să fie întotdeauna stocat în majuscule în baza de date, ignorând orice formatare a clientului JS.\nScrieți o funcție de declanșare numită „force_uppercase_name()”. Nu acceptă argumente ().\nReturnează TRIGGER. Creați șablonul de corp.\nForțați atribuirea întregului obiect primit prin atribuirea magică „NEW.first_name = UPPER(NEW.first_name);”. Apoi RETURNați variabila NEW remodelată.
Afișează indiciu
CREATE SAU ÎNLOCUITĂ FUNCȚIA force_uppercase_name() RETURNEAZĂ TRIGGER CA $$ BEGIN NEW.first_name = UPPER(NEW.first_name); RETURNARE NOU; SFÂRŞIT; $$ LIMBA plpgsql;
Soluție disponibilă după 3 încercări
Creați o funcție de declanșare „protect_price_drops()” care blochează actualizările rău intenționate în care un atacator este pe cale să economisească un preț ridicol de scăzut pentru un produs.\nUtilizați o logică precum „IF NEW.unit_price < OLD.unit_price THEN”, ridicând o excepție nativă care duce la prăbușire totul.\nO excepție fatală „EXEPTION SQL PL/sEg” non abbassabile!'';'.
Afișează indiciu
ÎNCEPEȚI DACĂ NEW.unit_price < OLD.unit_price ATUNCI CRESCĂ EXCEPȚIA „Prezzo non abbassabile!'; END IF; RETURNARE NOU; SFÂRŞIT;
Soluție disponibilă după 3 încercări