Lezioni del modulo (3/4)
Introduzione ai Trigger
Un trigger è una scatola magica (un sensore) che esegue in automatico un pezzo di logica PRIMA o DOPO un evento di inserimento, modifica o cancellazione nei dati.\nPrima però di insegnare ad una tabella a reagire c'è bisogno di fornirle una speciale "Funzione da Trigger" usando il PL/pgSQL che deve per forza terminare retornando un formato fittizio chiamato "TRIGGER".
Queste funzioni non accettano argomenti normali in parentesi ma offrono invece magici oggetti interni NEW e OLD gratuiti, i quali contengono le righe dati originali o nascenti della tabella da cui il sensore avverte!
CREATE OR REPLACE FUNCTION audit_deletions()
RETURNS TRIGGER AS $$
BEGIN
-- OLD.id è magicamente il valore dell'id del povero record che sta venendo eliminato
INSERT INTO audit_log (table_name, record_id, action)
VALUES (TG_TABLE_NAME, OLD.id, 'DELETE');
RETURN OLD; -- I trigger prima della route Delete devono concedere l'uscita
END;
$$ LANGUAGE plpgsql;Questa procedura fa l'hard-work di scrivere su log. Poi in un secondo step andrà allacciata permanentemente agli eventi della tabella che vogliamo proteggere.
Prova tu
Dobbiamo proteggere i clienti, nessuno con meno di 18 anni (la nostra check virtuale) o, al di fuori da fittizie logiche, vogliamo forzare che la stringa 'first_name' passata in fase di INSERT sia sempre e forzatamente scritta tutta in maisucolo nel database ignorando la formattazione JS client.\nScrivi una Trigger Function chiamata 'force_uppercase_name()'. Non accetta () argomenti.\nRitorna TRIGGER. Crea il template body.\nForza ed assegna l'intero object nascente via magico assegnatore 'NEW.first_name = UPPER(NEW.first_name);'. Poi RETURN in output la variabile NEW ritrattata.
Mostra suggerimento
CREATE OR REPLACE FUNCTION force_uppercase_name() RETURNS TRIGGER AS $$ BEGIN NEW.first_name = UPPER(NEW.first_name); RETURN NEW; END; $$ LANGUAGE plpgsql;
Soluzione disponibile dopo 3 tentativi
Crea una Trigger Function 'protect_price_drops()' che inibisca update malevoli dove un hacker sta per salvare un prezzo ridicolmente basso al prodotto.\nUsa una logica 'IF NEW.unit_price < OLD.unit_price THEN', sollevando un'eccezione nativa che fa crollare tutto.\nUn eccezione fatale PL/pgSQL usa il parametro 'RAISE EXCEPTION ''Prezzo non abbassabile!'';'.
Mostra suggerimento
BEGIN IF NEW.unit_price < OLD.unit_price THEN RAISE EXCEPTION 'Prezzo non abbassabile!'; END IF; RETURN NEW; END;
Soluzione disponibile dopo 3 tentativi