Utlösare
Svep för att visa menyn
Triggers i databaser är speciella typer av lagrade procedurer som automatiskt körs eller utlöses som svar på vissa händelser eller åtgärder som sker i databasen.
Dessa händelser kan inkludera insättningar, uppdateringar eller borttagningar av data i tabeller samt ändringar av databasens schemaobjekt som tabeller eller vyer.
DML-triggers
En DML-trigger, även kallad Data Manipulation Language-trigger, är ett databasobjekt som automatiskt utför en specificerad åtgärd när en viss händelse inträffar på en tabell eller vy.
DML-triggers används ofta för att upprätthålla affärsregler, säkerställa dataintegritet eller utföra granskning.
Typer av DML-triggers
- After Triggers: Dessa triggers utlöses efter att den utlösande åtgärden (insert, update, delete) har utförts på tabellen;
- Before Triggers: Dessa triggers utlöses innan den utlösande åtgärden. De gör det möjligt att fånga upp den ursprungliga åtgärden och utföra anpassad logik innan man bestämmer om den ursprungliga åtgärden ska fortsätta eller inte.
Exempel på after trigger
Vi har tidigare undersökt ett exempel där en transaktion används för att lägga till värden i tabellen BankAccounts och tabellen UserLogs som en enda logisk enhet i den första delen av denna kurs.
Nu, istället för att använda en transaktion, kan vi uppnå detta genom att skapa en AFTER-trigger på INSERT-operationen i tabellen BankAccounts.
Som ett resultat kommer vi endast kunna lägga till nya konton, och motsvarande loggpost kommer automatiskt att läggas till av triggern.
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();
-
Skapa en after insert-trigger för user_logs:
- Skapa en funktion med namnet
afterinserttriggerfunction(). - Funktionen är definierad för att returnera en trigger.
- Funktionens kropp börjar med ett
BEGIN-block. - Inuti
BEGIN-blocket utförs en åtgärd, vilket är att infoga en post i tabellenuserlogs. - Den infogade posten innehåller värden från den nya raden (
NEW) från den utlösande händelsen. - De värden som infogas inkluderar
accountnumberoch en sammansatt sträng som nämner åtgärden. - Funktionen returnerar den nya raden (
NEW). - Funktionen är skriven i språket
plpgsql.
- Skapa en funktion med namnet
-
Koppla triggern till tabellen bankaccounts:
- En trigger med namnet
afterinserttriggerskapas. - Triggern är inställd på att köras efter en
INSERT-operation på tabellenbankaccounts. - Triggern är inställd på att köra funktionen
afterinserttriggerfunctionför varje påverkad rad.
- En trigger med namnet
I PostgreSQL-triggers är NEW en speciell postvariabel som representerar den nya raden som infogas i eller uppdateras i tabellen. Den gör det möjligt att komma åt kolumnvärdena i den nya raden inom triggerfunktionen.
Om vi arbetar med borttagna rader måste vi använda postvariabeln OLD istället för NEW.
Exempel på BEFORE-trigger
Anta att vi vill förhindra att värden med negativ kontobalans läggs till. Vi kan skapa en BEFORE-trigger för att uppnå detta. Denna trigger kommer att kontrollera saldot före operationen, och om det är negativt kommer operationen inte att utföras.
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();
-
Skapa triggerfunktionen:
- Skapa eller ersätt en funktion med namnet
before_insert_userlogs(). - Funktionen är definierad för att returnera en trigger.
- Funktionens kropp börjar med ett
BEGIN-block. - Inuti
BEGIN-blocket kontrolleras om kontosaldot är mindre än 0. - Om saldot är mindre än 0 höjs ett meddelande och ingen åtgärd loggas. Funktionen returnerar NULL för att förhindra insättning.
- Om saldot är större än eller lika med 0 höjs ett meddelande som indikerar att åtgärden loggas.
- Funktionen infogar sedan en post i tabellen
userlogs, med värden från den nya raden (NEW). - De insatta värdena inkluderar
accountnumberoch en sammansatt sträng som indikerar åtgärden. - Funktionen returnerar
NEWför att tillåta insättningen att fortsätta. - Funktionen är skriven i språket
plpgsql.
- Skapa eller ersätt en funktion med namnet
-
Skapa triggern:
- En trigger med namnet
before_insert_userlogs_triggerskapas. - Triggern är inställd på att köras före en
INSERT-operation på tabellenbankaccounts. - Triggern är inställd på att köra funktionen
before_insert_userlogs()för varje påverkad rad.
- En trigger med namnet
Mönster för skapande av triggers
Vi kan observera det typiska mönstret för att skapa triggers: först definierar vi en funktion för att utföra specifik logik före eller efter en operation. Därefter associerar vi denna funktion som en trigger till en angiven tabell och åtgärd.
Observera att i satsen:
CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW
EXECUTE PROCEDURE proc_name;
har vi flexibiliteten att använda UPDATE eller DELETE istället för INSERT-operationen.
Men observera att vi inte kan skapa SELECT-triggers eftersom SELECT-satsen inte ändrar några rader i tabellen!
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal