Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle - Problem beim Erstellen eines Triggers, der eine andere Tabelle aktualisiert

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;