Triggere
Stryg for at vise menuen
Triggers i databaser er særlige typer af lagrede procedurer, der automatisk udføres eller aktiveres som reaktion på bestemte hændelser eller handlinger, der forekommer i databasen.
Disse hændelser kan omfatte indsættelser, opdateringer eller sletninger af data i tabeller samt ændringer af databaseskemaobjekter som tabeller eller views.
DML-triggere
En DML-trigger, også kendt som en Data Manipulation Language-trigger, er et databaseobjekt, der automatisk udfører en specificeret handling, når en bestemt hændelse opstår på en tabel eller et view.
DML-triggere bruges ofte til at håndhæve forretningsregler, opretholde dataintegritet eller udføre revisionsopgaver.
Typer af DML-triggere
- After Triggers: Disse triggere aktiveres efter den udløsende handling (insert, update, delete) er udført på tabellen;
- Before Triggers: Disse triggere aktiveres før den udløsende handling. De giver mulighed for at opsnappe den oprindelige handling og udføre brugerdefineret logik, før der tages stilling til, om den oprindelige handling skal fortsætte.
Eksempel på after-trigger
Vi har tidligere undersøgt et eksempel på brug af en transaktion til at tilføje værdier til BankAccounts-tabellen og UserLogs-tabellen som en enkelt logisk enhed i den første sektion af dette kursus.
Nu kan vi i stedet for at bruge en transaktion opnå dette ved at oprette en AFTER-trigger på INSERT-operationen i BankAccounts-tabellen.
Som resultat vil vi kun kunne indsætte nye konti, og den tilsvarende logværdi vil automatisk blive tilføjet af triggeren.
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();
-
Opret en after insert-trigger for user_logs:
- Opret en funktion med navnet
afterinserttriggerfunction(). - Funktionen er defineret til at returnere en trigger.
- Funktionens krop begynder med et
BEGIN-blok. - Inde i
BEGIN-blokken udføres en handling, som er at indsætte en post iuserlogs-tabellen. - Den indsatte post indeholder værdier fra
NEW-rækken fra den udløsende hændelse. - De indsatte værdier inkluderer
accountnumberog en sammenkædet streng, der nævner handlingen. - Funktionen returnerer
NEW-rækken. - Funktionen er skrevet i
plpgsql-sproget.
- Opret en funktion med navnet
-
Tilknyt triggeren til bankaccounts-tabellen:
- En trigger med navnet
afterinserttriggeroprettes. - Triggeren er sat til at blive udført efter en
INSERT-operation påbankaccounts-tabellen. - Triggeren er sat til at udføre funktionen
afterinserttriggerfunctionfor hver berørt række.
- En trigger med navnet
I PostgreSQL-triggere er NEW en speciel record-variabel, der repræsenterer den nye række, der indsættes i eller opdateres i tabellen. Den giver adgang til værdierne af kolonnerne i den nye række inden for trigger-funktionen.
Hvis vi arbejder med slettede rækker, skal vi bruge OLD record-variablen i stedet for NEW.
Eksempel på før-trigger
Antag, at vi vil forhindre tilføjelse af værdier med en negativ kontosaldo. Vi kan oprette en BEFORE trigger for at opnå dette. Denne trigger vil kontrollere saldoen før operationen, og hvis den er negativ, vil operationen ikke blive udført.
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();
-
Opret trigger-funktionen:
- Opret eller erstat en funktion med navnet
before_insert_userlogs(). - Funktionen er defineret til at returnere en trigger.
- Funktionens krop begynder med et
BEGIN-blok. - Inde i
BEGIN-blokken kontrolleres det, om kontosaldoen er mindre end 0. - Hvis saldoen er mindre end 0, gives der en meddelelse, og ingen handling logges. Funktionen returnerer NULL for at forhindre indsættelsen.
- Hvis saldoen er større end eller lig med 0, gives der en meddelelse, der angiver, at handlingen logges.
- Funktionen indsætter derefter en post i tabellen
userlogs, som indeholder værdier fra den nye række (NEW). - De indsatte værdier inkluderer
accountnumberog en sammenkædet streng, der angiver handlingen. - Funktionen returnerer
NEWfor at tillade indsættelsen at fortsætte. - Funktionen er skrevet i
plpgsql-sproget.
- Opret eller erstat en funktion med navnet
-
Opret triggeren:
- En trigger med navnet
before_insert_userlogs_triggeroprettes. - Triggeren er sat til at blive udført før en
INSERT-operation på tabellenbankaccounts. - Triggeren er sat til at udføre funktionen
before_insert_userlogs()for hver berørt række.
- En trigger med navnet
Mønster for oprettelse af triggers
Vi kan observere det typiske mønster for oprettelse af triggers: først definerer vi en funktion til at udføre specifik logik før eller efter en operation. Derefter tilknytter vi denne funktion som en trigger til en bestemt tabel og handling.
Bemærk venligst, at i følgende erklæring:
CREATE TRIGGER trigger_name
AFTER INSERT ON table_name
FOR EACH ROW
EXECUTE PROCEDURE proc_name;
har vi fleksibiliteten til at anvende UPDATE eller DELETE i stedet for INSERT-operationen.
Men vær opmærksom på, at vi ikke kan oprette SELECT-triggers, da SELECT-sætningen ikke ændrer nogen rækker i tabellen!
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat