Oracle PL/SQL-trigger: I stedet for &-sammensatte typer

โšก Smart opsummering

PL/SQL-triggere er lagrede programmer, som Oracle Motoren starter automatisk, nรฅr en DML-, DDL- eller databasehรฆndelse opstรฅr. De opretholder dataintegritet, hรฅndhรฆver regler og understรธtter revision, og de inkluderer Fร˜R-, EFTER-, I STEDET FOR- og sammensatte typer.

  • ๐Ÿ”” Triggerdefinition: En trigger er et lagret program, Oracle Motoren starter automatisk ved en bestemt DML-, DDL- eller databasehรฆndelse.
  • ๐ŸŽฏ Triggertyper: Udlรธsere klassificeres efter timing (Fร˜R, EFTER, I STEDET FOR), niveau (UDSร†TNING, Rร†KKE) og hรฆndelse (DML, DDL, DATABASE).
  • ๐Ÿ” :NY og :GAMMEL: Udlรธsere pรฅ rรฆkkeniveau bruger :NEW- og :OLD-klausulerne til at lรฆse kolonnevรฆrdier fรธr og efter DML-sรฆtningen.
  • ๐ŸชŸ I STEDET FOR Udlรธser: En INSTEAD OF-trigger gรธr en ellers ikke-opdaterbar kompleks visning modificerbar ved at reagere pรฅ dens basistabeller.
  • ๐Ÿงฉ Sammensat udlรธser: En sammensat trigger kombinerer handlinger for alle fire timingpunkter i รฉn triggerkrop.
  • ๐Ÿค– AI Assistance: AI-assistenter som f.eks. GitHub Copilot-kladder Fร˜R, EFTER, I STEDET FOR og sammensatte triggere fra en kommentar.

Oracle PL/SQL-triggere, inklusive INSTEAD OF og sammensatte triggertyper

Hvad er Trigger i PL/SQL?

TRIGGERE er gemt PL / SQL programmer, der udlรธses af Oracle motoren automatisk nรฅr DML erklรฆringer som f.eks. insert, update og delete udfรธres pรฅ tabellen, eller nรฅr der opstรฅr hรฆndelser. Den kode, der skal udfรธres i tilfรฆlde af en trigger, kan defineres efter behov. Du kan vรฆlge den hรฆndelse, hvorpรฅ triggeren skal udlรธses, og timingen af โ€‹โ€‹udfรธrelsen. Formรฅlet med en trigger er at opretholde integriteten af โ€‹โ€‹informationen i databasen.

Fordele ved triggere

Fรธlgende er fordelene ved triggere.

  • Generering af nogle afledte kolonnevรฆrdier automatisk
  • Hรฅndhรฆvelse af referentiel integritet
  • Hรฆndelseslogning og lagring af information om bordadgang
  • Revision
  • Synchรธflig replikering af tabeller
  • Indfรธrelse af sikkerhedsgodkendelser
  • Forebyggelse af ugyldige transaktioner

Typer af triggere i Oracle

Triggere kan klassificeres baseret pรฅ fรธlgende parametre.

Klassificering baseret pรฅ tidspunktet

  • Fร˜R udlรธser: Den udlรธses, fรธr den angivne hรฆndelse er indtruffet.
  • EFTER udlรธser: Den udlรธses efter den angivne hรฆndelse er indtruffet.
  • I STEDET FOR Udlรธser: En sรฆrlig type. Du vil lรฆre mere i de fรธlgende emner. (kun for DML)

Klassificering baseret pรฅ niveau

  • Udlรธser pรฅ STATUS-niveau: Den udlรธses รฉn gang for den angivne hรฆndelsessรฆtning.
  • ROW-niveau-udlรธser: Den udlรธses for hver post, der blev pรฅvirket af den angivne hรฆndelse. (kun for DML)

Klassificering baseret pรฅ begivenheden

  • DML-udlรธser: Den udlรธses, nรฅr DML-hรฆndelsen er angivet (INSERT/UPDATE/DELETE).
  • DDL-udlรธser: Den udlรธses, nรฅr DDL-hรฆndelsen er angivet (CREATE/ALTER).
  • DATABASE-trigger: Den aktiveres, nรฅr databasehรฆndelsen er angivet (LOGON/LOGOFF/STARTUP/SHUTDOWN).

Sรฅ hver trigger er en kombination af ovenstรฅende parametre.

Sรฅdan opretter du trigger

Nedenfor er syntaksen for oprettelse af en trigger. Skรฆrmbilledet nedenfor viser denne syntaks for oprettelse af trigger i Oracle.

Syntaks for udlรธseroprettelse med mulighederne Fร˜R, EFTER og I STEDET FOR i Oracle PL / SQL

CREATE [ OR REPLACE ] TRIGGER <trigger_name> 

[BEFORE | AFTER | INSTEAD OF ]

[INSERT | UPDATE | DELETE......]

ON<name of underlying object>

[FOR EACH ROW] 

[WHEN<condition for trigger to get execute> ]

DECLARE
<Declaration part>
BEGIN
<Execution part> 
EXCEPTION
<Exception handling part> 
END;

Syntaks forklaring:

  • Ovenstรฅende syntaks viser de forskellige valgfrie udsagn, der er til stede i triggeroprettelse.
  • Fร˜R/EFTER vil specificere begivenhedstidspunkterne.
  • INSERT/OPDATERING/LOGON/CREATE/osv. vil angive den hรฆndelse, som udlรธseren skal udlรธses for.
  • ON-klausulen angiver det objekt, hvor ovennรฆvnte hรฆndelse er gyldig. For eksempel vil dette vรฆre tabelnavnet, hvor DML-hรฆndelsen kan forekomme i tilfรฆlde af en DML-trigger.
  • Kommandoen "FOR EACH ROW" angiver ROW-niveau-triggeren.
  • WHEN-klausulen angiver den yderligere betingelse, hvorunder udlรธseren skal udlรธses.
  • Deklarationsdelen, udfรธrelsesdelen og undtagelseshรฅndteringsdelen er de samme som i de andre PL/SQL blokkeErklรฆringsdelen og undtagelse hรฅndtering del er valgfri.

:NY og :GAMMEL klausul

I en trigger pรฅ rรฆkkeniveau udlรธses triggeren for hver relateret rรฆkke. Og nogle gange er det nรธdvendigt at kende vรฆrdien fรธr og efter DML-sรฆtningen.

Oracle har angivet to klausuler i rรฆkkeniveau-triggeren til at indeholde disse vรฆrdier. Vi kan bruge disse klausuler til at referere til de gamle og nye vรฆrdier i triggerens brรธdtekst.

  • :NY โ€“ Den indeholder en ny vรฆrdi for kolonnerne i basistabellen/-visningen under udlรธserudfรธrelsen.
  • :GAMMEL โ€“ Den gemmer den gamle vรฆrdi af kolonnerne i basistabellen/-visningen under triggerudfรธrelsen.

Denne klausul skal bruges baseret pรฅ DML-hรฆndelsen. Tabellen nedenfor angiver, hvilken klausul der er gyldig for hvilken DML-sรฆtning (INSERT/UPDATE/DELETE).

INSERT OPDATER SLET
:NY GYLDIG GYLDIG UGYLDIG. Der er ingen ny vรฆrdi i slettetilfรฆldet.
:GAMMEL UGYLDIG. Der er ingen gammel vรฆrdi i insert-sag/sag. GYLDIG GYLDIG

I STEDET FOR Trigger

En "INSTEAD OF trigger" er en sรฆrlig type trigger. Den bruges kun i DML-triggere. Den bruges, nรฅr en DML-hรฆndelse vil forekomme i en kompleks visning.

Overvej et eksempel, hvor en visning er lavet ud fra tre basistabeller. Nรฅr en DML-hรฆndelse udstedes over denne visning, bliver den ugyldig, fordi dataene er taget fra tre forskellige tabeller. Sรฅ i dette tilfรฆlde bruges en INSTEAD OF-trigger. INSTEAD OF-triggeren bruges til at รฆndre basistabellerne direkte i stedet for at รฆndre visningen for den givne hรฆndelse.

Eksempel 1: I dette eksempel skal vi oprette en kompleks visning ud fra to basistabeller, hvor Tabel_1 er lejrtabellen og Tabel_2 er afdelingstabellen.

Derefter skal vi se, hvordan INSTEAD OF-triggeren bruges til at udstede en UPDATE af placeringsdetaljerne i denne komplekse visning. Vi skal ogsรฅ se, hvordan :NEW og :OLD er nyttige i triggere. Eksemplet udfรธres i fรธlgende trin:

  • Trin 1: Oprettelse af tabellerne 'emp' og 'dept' med passende kolonner
  • Trin 2: Udfyldning af tabellerne med eksempelvรฆrdier
  • Trin 3: Oprettelse af en visning for de ovennรฆvnte tabeller
  • Trin 4: Opdatering af visningen fรธr INSTEAD OF-triggeren
  • Trin 5: Oprettelse af INSTEAD OF-triggeren
  • Trin 6: Opdatering af visningen efter INSTEAD OF-triggeren

Trin 1) Oprettelse af tabellerne 'emp' og 'dept' med passende kolonner.

Skรฆrmbilledet nedenfor viser oprettelsen af โ€‹โ€‹basistabellerne 'emp' og 'dept' i Oracle.

Oprettelse af basistabellerne for medarbejder og afdeling i Oracle for eksemplet med udlรธseren I STEDET FOR

CREATE TABLE emp(
emp_no NUMBER,
emp_name VARCHAR2(50),
salary NUMBER,
manager VARCHAR2(50),
dept_no NUMBER);
/

CREATE TABLE dept(
Dept_no NUMBER,
Dept_name VARCHAR2(50),
LOCATION VARCHAR2(50));
/

Code Forklaring

  • Code linje 1-7: Oprettelse af tabel 'employ'.
  • Code linje 8-12: Oprettelse af tabel 'afdeling'.

Output:

Table Created

Trin 2) Nu hvor vi har oprettet tabellerne, vil vi udfylde dem med eksempelvรฆrdier.

Skรฆrmbilledet nedenfor viser eksempelrรฆkkerne, der indsรฆttes i tabellerne 'dept' og 'emp'.

Indsรฆttelse af eksempelafdelings- og medarbejderrรฆkker i Oracle PL / SQL

BEGIN
INSERT INTO DEPT VALUES(10,'HR','USA');
INSERT INTO DEPT VALUES(20,'SALES','UK');
INSERT INTO DEPT VALUES(30,'FINANCIAL','JAPAN');
COMMIT;
END;
/

BEGIN
INSERT INTO EMP VALUES(1000,'XXX',15000,'AAA',30);
INSERT INTO EMP VALUES(1001,'YYY',18000,'AAA',20) ;
INSERT INTO EMP VALUES(1002,'ZZZ',20000,'AAA',10);
COMMIT;
END;
/

Code Forklaring

  • Code linje 13-19: Indsรฆttelse af data i 'afdeling'-tabellen.
  • Code linje 20-26: Indsรฆttelse af data i tabellen 'emp'.

Output:

PL/SQL procedure completed

Trin 3) Opretter en visning for ovenstรฅende tabeller.

Skรฆrmbilledet nedenfor viser den komplekse visning, der oprettes og derefter forespรธrges.

Oprettelse og forespรธrgsel pรฅ den komplekse visning guru99_emp_view, der forbinder emp og dept

CREATE VIEW guru99_emp_view(
Employee_name,dept_name,location) AS
SELECT emp.emp_name,dept.dept_name,dept.location
FROM emp,dept
WHERE emp.dept_no=dept.dept_no;
/
SELECT * FROM guru99_emp_view;

Code Forklaring

  • Code linje 27-32: Oprettelse af visningen 'guru99_emp_view'.
  • Code linje 33: Forespรธrger guru99_emp_view.

Output:

View created
ANSATTES NAVN DEPT_NAME ADRESSE
ZZZ HR Danmark
yyy SALG UK
XXX FINANSIEL JAPAN

Trin 4) Opdatering af visningen fรธr INSTEAD OF-triggeren.

Skรฆrmbilledet nedenfor viser opdateringsforsรธget i den komplekse visning og den resulterende fejl.

Opdatering om den komplekse visning, der fejler med ORA-01779 fรธr INSTEAD OF-triggeren

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX';
COMMIT;
END;
/

Code Forklaring

  • Code linje 34-38: Opdater placeringen af โ€‹โ€‹"XXX" til 'FRANCE'. Der opstod en undtagelse, fordi DML-sรฆtninger ikke er tilladt direkte i den komplekse visning.

Output:

ORA-01779: cannot modify a column which maps to a non key-preserved table

ORA-06512: at line 2

Trin 5) For at undgรฅ den fejl, der opstod under opdatering af visningen i det forrige trin, vil vi i dette trin bruge en "INSTEAD OF"-trigger.

Skรฆrmbilledet nedenfor viser oprettelsen af โ€‹โ€‹INSTEAD OF-triggeren.

Oprettelse af guru99_view_modify_trg I STEDET FOR trigger pรฅ den komplekse visning

CREATE TRIGGER guru99_view_modify_trg
INSTEAD OF UPDATE
ON guru99_emp_view
FOR EACH ROW
BEGIN
UPDATE dept
SET location=:new.location
WHERE dept_name=:old.dept_name;
END;
/

Code Forklaring

  • Code linje 39: Oprettelse af INSTEAD OF-triggeren for 'UPDATE'-hรฆndelsen i 'guru99_emp_view'-visningen pรฅ ROW-niveau. Den indeholder opdateringssรฆtningen til at opdatere placeringen i basistabellen 'dept'.
  • Code linje 44: Opdateringssรฆtningen bruger ':NEW' og ':OLD' til at finde vรฆrdien af โ€‹โ€‹kolonner fรธr og efter opdateringen.

Output:

Trigger Created

Trin 6) Opdatering af visningen efter INSTEAD OF-triggeren. Fejlen vil nu ikke vises, da "INSTEAD OF-triggeren" vil hรฅndtere opdateringshandlingen for denne komplekse visning. Nรฅr koden udfรธres, vil placeringen af โ€‹โ€‹medarbejder XXX blive opdateret til "Frankrig" fra "Japan".

Skรฆrmbilledet nedenfor viser den vellykkede opdatering via INSTEAD OF-triggeren og den opdaterede visning.

Opdatering af visning via INSTEAD OF-triggeren, der viser placeringen FRANKRIG

BEGIN
UPDATE guru99_emp_view SET location='FRANCE' WHERE employee_name='XXX';
COMMIT;
END;
/
SELECT * FROM guru99_emp_view;

Code Forklaring:

  • Code linje 49-53: Opdatering af placeringen af โ€‹โ€‹โ€œXXXโ€ til 'FRANCE'. Det er lykkedes, fordi 'INSTEAD OF'-triggeren har stoppet den faktiske opdateringssรฆtning pรฅ visningen og udfรธrt opdateringen af โ€‹โ€‹basistabellen.
  • Code linje 55: Bekrรฆfter den opdaterede post.

Output:

PL/SQL procedure successfully completed
ANSATTES NAVN DEPT_NAME ADRESSE
ZZZ HR Danmark
yyy SALG UK
XXX FINANSIEL FRANKRIG

Sammensat trigger

Den sammensatte trigger er en trigger, der giver dig mulighed for at angive handlinger for hvert af fire timingpunkter i en enkelt triggerkrop. De fire forskellige timingpunkter, den understรธtter, er som fรธlger.

  • Fร˜R UDTALELSE โ€“ niveau
  • Fร˜R Rร†KKE โ€“ niveau
  • EFTER Rร†KKE โ€“ niveau
  • EFTER UDTALELSE โ€“ niveau

Det giver mulighed for at kombinere handlingerne for forskellige timings i den samme trigger.

Skรฆrmbilledet nedenfor viser den sammensatte triggersyntaks med dens fire timing-sektioner.

Sammensat triggersyntaks, der viser Fร˜R- og EFTER-sรฆtninger og rรฆkketiming-sektioner

CREATE [ OR REPLACE ] TRIGGER <trigger_name>
FOR
[INSERT | UPDATE | DELETE.......]
ON <name of underlying object>
<Declarative part>
BEFORE STATEMENT IS
BEGIN
<Execution part>;
END BEFORE STATEMENT;

BEFORE EACH ROW IS
BEGIN
<Execution part>;
END EACH ROW;

AFTER EACH ROW IS
BEGIN
<Execution part>;
END AFTER EACH ROW;

AFTER STATEMENT IS
BEGIN
<Execution part>;
END AFTER STATEMENT;
END;

Syntaks forklaring:

  • Ovenstรฅende syntaks viser oprettelsen af โ€‹โ€‹en 'COMPOUND'-trigger.
  • Den deklarative sektion er fรฆlles for alle udfรธrelsesblokke i trigger-brรธdteksten.
  • Disse fire timingblokke kan vรฆre i en hvilken som helst rรฆkkefรธlge. Det er ikke obligatorisk at have alle fire timingblokke. Vi kan oprette en COMPOUND-trigger kun for de timinger, der er nรธdvendige.

Eksempel 1: I dette eksempel opretter vi en trigger til automatisk at udfylde lรธnkolonnen med standardvรฆrdien 5000.

Skรฆrmbilledet nedenfor viser eksemplet pรฅ den sammensatte trigger og dens output.

Sammensat trigger udfylder automatisk lรธnkolonnen med en standardvรฆrdi pรฅ 5000

CREATE TRIGGER emp_trig
FOR INSERT
ON emp
COMPOUND TRIGGER
BEFORE EACH ROW IS
BEGIN
:new.salary:=5000;
END BEFORE EACH ROW;
END emp_trig;
/
BEGIN
INSERT INTO EMP VALUES(1004,'CCC',15000,'AAA',30);
COMMIT;
END;
/
SELECT * FROM emp WHERE emp_no=1004;

Code Forklaring:

  • Code linje 2-10: Oprettelse af den sammensatte trigger. Den oprettes til timingniveauet BEFORE ROW for at udfylde lรธnnen med standardvรฆrdien 5000. Dette vil รฆndre lรธnnen til standardvรฆrdien '5000', fรธr posten indsรฆttes i tabellen.
  • Code linje 11-14: Indsรฆt posten i tabellen 'emp'.
  • Code linje 16: Bekrรฆfter den indsatte post.

Output:

Trigger created

PL/SQL procedure successfully completed.
EMP_NAME EMP_NO Lร˜N MANAGER DEPT_NO
CCC 1004 5000 AAA 30

Aktivering og deaktivering af triggere

Triggere kan aktiveres eller deaktiveres. For at aktivere eller deaktivere en trigger skal der gives en ALTER (DDL)-sรฆtning for den trigger, der deaktiverer eller aktiverer den.

Nedenfor er syntaksen for aktivering/deaktivering af udlรธserne.

ALTER TRIGGER <trigger_name> [ENABLE|DISABLE];
ALTER TABLE <table_name> [ENABLE|DISABLE] ALL TRIGGERS;

Syntaks forklaring:

  • Den fรธrste syntaks viser, hvordan man aktiverer/deaktiverer en enkelt trigger.
  • Den anden sรฆtning viser, hvordan du aktiverer/deaktiverer alle triggere pรฅ en bestemt tabel.

Ofte Stillede Spรธrgsmรฅl

Fejlen ORA-04091, der forรฅrsager mutation af tabellen, opstรฅr, nรฅr en rรฆkkeniveau-trigger forsรธger at forespรธrge eller รฆndre den samme tabel, der udlรธste den. Undgรฅ dette ved at bruge en sammensat trigger, en sรฆtningsniveau-trigger eller ved i stedet at holde rรฆkker i en pakkesamling.

En trigger aktiveres automatisk, nรฅr en DML-, DDL- eller databasehรฆndelse opstรฅr, tager ingen parametre og returnerer ingenting. lagret procedure kรธrer kun nรฅr du eksplicit kalder den, accepterer parametre og kan returnere vรฆrdier.

Brug DROP TRIGGER trigger_name-sรฆtningen til at fjerne en trigger permanent. I modsรฆtning til deaktivering, som bevarer triggeren, men forhindrer den i at blive udlรธst, skal du fjerneping sletter definitionen helt, sรฅ du skal genskabe den, hvis logikken er nรธdvendig igen.

Forespรธrg dataordbogsvisningerne USER_TRIGGERS for dine egne triggere eller ALL_TRIGGERS for hver trigger, du har adgang til. De viser triggernavn, type, triggerhรฆndelse, basisobjekt og status, hvilket hjรฆlper dig med at revidere eksisterende triggere.

Ikke direkte, fordi udlรธseren deler affyringserklรฆringens transaktionFor at committe uafhรฆngigt skal du deklarere triggeren, eller en procedure, den kalder, med PRAGMA AUTONOMOUS_TRANSACTION, som kรธrer arbejdet i en separat transaktion, der committer alene.

Fรธr Oracle 11g var rรฆkkefรธlgen af โ€‹โ€‹samme type triggere ikke garanteret. Fra 11g og fremefter lader FOLLOWS-klausulen i CREATE TRIGGER-sรฆtningen dig angive, at รฉn trigger udlรธses efter den anden, hvilket giver en deterministisk udfรธrelsesrรฆkkefรธlge.

Ja. GitHub Copilot udkast Fร˜R, EFTER, I STEDET FOR og sammensatte udlรธsere, inklusive :NYE og :GAMMLE referencer, fra en kommentar. RevSe timingen, WHEN-betingelsen og muterende tabelrisici, fรธr den genererede trigger implementeres.

AI-assistenter scanner triggere for muterende tabeller, manglende :NEW- eller :OLD-hรฅndtering, rekursiv aktivering og tung logik, der bremser DML. Denne maskinlรฆringsgennemgang markerer skrรธbelige triggere og foreslรฅr omskrivninger pรฅ sรฆtningsniveau eller sammensatte koder, fรธr koden nรฅr produktion.

Opsummer dette indlรฆg med: