Et par problemer i nogen bestemt rækkefølge.
For det første skal du bruge :new
i brødteksten af en trigger på rækkeniveau og :old
at referere til de nye og gamle optegnelser. Den ledende kolon er nødvendig. Så din WHERE
klausul skulle være
WHERE PROJECTID = :new.PROJECTID
For det andet, hvis du kører din CREATE TRIGGER
i SQL*Plus kan du få en liste over fejl og advarsler ved hjælp af SHOW ERRORS
kommando, dvs.
SQL> show errors
Du kan også forespørge på DBA_ERRORS
tabel (eller ALL_ERRORS
eller USER_ERRORS
afhængigt af dit privilegieniveau), men det er ikke noget, du normalt behøver at ty til.
For det tredje, forudsat at syntaksfejlene bliver rettet, vil du få en mutering tabelfejl
hvis du bruger denne logik. En udløser på rækkeniveau i tabel A (TPM_TRAININGPLAN
i dette tilfælde) kan ikke forespørge tabel A, fordi tabellen kan være i en inkonsistent tilstand. Du kan omgå det, som Tim viser i sin artikel, ved at oprette en pakke med en samling, initialisere den samling i en før-sætningsudløser, udfylde dataene i samlingen i en trigger på rækkeniveau og derefter behandle de ændrede rækker i en efterudsagnsudløser. Det er dog en anstændig mængde kompleksitet at tilføje til systemet, da du bliver nødt til at administrere flere forskellige objekter.
Generelt ville du være bedre stillet at implementere denne logik som en del af den API, du bruger til at manipulere TPM_TRAININGPLAN
bord. Hvis det er en lagret procedure, giver det meget mere mening at sætte logikken til at opdatere TPM_PROJECT
i den lagrede procedure i stedet for at sætte den i en trigger. Det er notorisk smertefuldt at forsøge at fejlsøge en applikation, der har en masse logik indlejret i triggere, fordi det gør det meget vanskeligt for udviklere at følge præcis, hvilke operationer der udføres. Alternativt kan du fjerne TRAININGDELIVERYSTART
kolonne fra TPM_PROJECT
tabel og udregn den mindste startdato ved kørsel.
For det fjerde, hvis din trigger udløses ved indsættelser, opdateringer og sletninger, kan du ikke blot henvise til :new
værdier. :new
er gyldig for indsættelser og opdateringer, men det vil være NULL, hvis du sletter. :old
er gyldig til sletninger og opdateringer, men vil være NULL, hvis du laver en indsættelse. Det betyder, at du sandsynligvis skal have logik i retning af (med henvisning til Tims pakkeløsning)
BEGIN
IF inserting
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'INSERT');
ELSIF updating
THEN
trigger_api.tab1_row_change(p_id => :new.projectid, p_action => 'UPDATE');
ELSIF deleting
THEN
trigger_api.tab1_row_change(p_id => :old.projectid, p_action => 'DELETE');
END IF;
END;