Ein paar Ausgaben in keiner bestimmten Reihenfolge.
Zuerst müssen Sie im Hauptteil eines Triggers auf Zeilenebene :new
verwenden und :old
um auf die neuen und alten Aufzeichnungen zu verweisen. Der führende Doppelpunkt ist erforderlich. Also Ihr WHERE
-Klausel müsste sein
WHERE PROJECTID = :new.PROJECTID
Zweitens, wenn Sie Ihren CREATE TRIGGER
ausführen In SQL*Plus können Sie mit SHOW ERRORS
eine Liste der Fehler und Warnungen abrufen Befehl, also
SQL> show errors
Sie könnten auch DBA_ERRORS
abfragen Tabelle (oder ALL_ERRORS
oder USER_ERRORS
abhängig von Ihrer Berechtigungsebene), aber darauf müssen Sie normalerweise nicht zurückgreifen.
Drittens, vorausgesetzt, die Syntaxfehler werden korrigiert, erhalten Sie eine Mutation Tabellenfehler
wenn Sie diese Logik verwenden. Ein Trigger auf Zeilenebene für Tabelle A (TPM_TRAININGPLAN
in diesem Fall) kann Tabelle A nicht abfragen, da sich die Tabelle möglicherweise in einem inkonsistenten Zustand befindet. Sie können dies umgehen, wie Tim in seinem Artikel zeigt, indem Sie ein Paket mit einer Sammlung erstellen, diese Sammlung in einem Before-Statement-Trigger initialisieren, die Daten in der Sammlung in einem Trigger auf Zeilenebene füllen und dann die geänderten Zeilen verarbeiten ein After-Statement-Trigger. Das ist jedoch eine anständige Menge an Komplexität, die Sie dem System hinzufügen können, da Sie mehrere verschiedene Objekte verwalten müssen.
Im Allgemeinen sollten Sie diese Logik besser als Teil der API implementieren, die Sie zum Bearbeiten des TPM_TRAININGPLAN
verwenden Tisch. Wenn es sich um eine gespeicherte Prozedur handelt, ist es viel sinnvoller, die Logik zum Aktualisieren von TPM_PROJECT
einzusetzen in dieser gespeicherten Prozedur, anstatt sie in einen Trigger einzufügen. Es ist notorisch mühsam, eine Anwendung zu debuggen, die viel Logik in Trigger eingebettet hat, da dies es Entwicklern sehr schwer macht, genau zu verfolgen, welche Operationen ausgeführt werden. Alternativ können Sie TRAININGDELIVERYSTART
entfernen Spalte aus TPM_PROJECT
Tabelle und berechnen Sie einfach das minimale Startdatum zur Laufzeit.
Viertens, wenn Ihr Trigger bei Einfügungen, Aktualisierungen und Löschungen ausgelöst wird, können Sie nicht einfach auf :new
verweisen Werte. :new
ist für Einfügungen und Aktualisierungen gültig, aber es wird NULL sein, wenn Sie eine Löschung durchführen. :old
ist für Löschungen und Aktualisierungen gültig, wird aber NULL sein, wenn Sie eine Einfügung vornehmen. Das bedeutet, dass Sie wahrscheinlich eine Logik in der Art von (mit Verweis auf Tims Paketlösung) haben müssen
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;