Några problem i ingen speciell ordning.
Först måste du använda :new
i kroppen av en utlösare på radnivå och :old
för att referera till nya och gamla register. Den ledande kolon är nödvändig. Så din WHERE
klausul skulle behöva vara
WHERE PROJECTID = :new.PROJECTID
För det andra, om du kör din CREATE TRIGGER
i SQL*Plus kan du få en lista över fel och varningar med hjälp av SHOW ERRORS
kommando, dvs.
SQL> show errors
Du kan också fråga DBA_ERRORS
tabell (eller ALL_ERRORS
eller USER_ERRORS
beroende på din privilegienivå) men det är inget du normalt behöver ta till.
För det tredje, förutsatt att syntaxfelen korrigeras, kommer du att få en mutering tabellfel
om du använder denna logik. En radnivåutlösare i tabell A (TPM_TRAININGPLAN
i det här fallet) kan inte fråga tabell A eftersom tabellen kan vara i ett inkonsekvent tillstånd. Du kan kringgå det, som Tim visar i sin artikel, genom att skapa ett paket med en samling, initiera den samlingen i en before-utlösare, fylla i data i samlingen i en utlösare på radnivå och sedan bearbeta de modifierade raderna i en efter uttalande trigger. Det är dock en anständig mängd komplexitet att lägga till i systemet, eftersom du måste hantera flera olika objekt.
Generellt sett är det bättre för dig att implementera denna logik som en del av vilket API du än använder för att manipulera TPM_TRAININGPLAN
tabell. Om det är en lagrad procedur är det mycket mer meningsfullt att använda logiken för att uppdatera TPM_PROJECT
i den lagrade proceduren snarare än att sätta den i en trigger. Det är notoriskt smärtsamt att försöka felsöka en applikation som har mycket logik inbäddad i triggers eftersom det gör det mycket svårt för utvecklare att följa exakt vilka operationer som utförs. Alternativt kan du ta bort TRAININGDELIVERYSTART
kolumn från TPM_PROJECT
tabell och bara beräkna det lägsta startdatumet vid körning.
För det fjärde, om din trigger aktiveras vid infogning, uppdatering och borttagning, kan du inte bara referera till :new
värden. :new
är giltigt för infogningar och uppdateringar men det kommer att vara NULL om du gör en radering. :old
är giltig för raderingar och uppdateringar men kommer att vara NULL om du gör en infogning. Det betyder att du förmodligen behöver ha logik i linje med (med hänvisning till Tims paketlö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;