Es ist (oder war zumindest bekannt), dass Sie keine DML-Anweisungen für eine mutierende Tabelle in einem Trigger verwenden können. Ein Auszug aus der Oracle-Dokumentation :
Eine mutierende Tabelle ist eine Tabelle, die durch eine UPDATE-, DELETE- oder INSERT-Anweisung geändert wird, oder eine Tabelle, die möglicherweise durch die Auswirkungen einer DELETE CASCADE-Einschränkung aktualisiert wird.
Die Sitzung, die die auslösende Anweisung ausgegeben hat, kann keine mutierende Tabelle abfragen oder ändern. Diese Einschränkung verhindert, dass ein Trigger einen inkonsistenten Datensatz sieht.
Ich kann jedoch nicht verstehen, warum dieser Demo-Trigger nicht mit einem "Mutating Table" -Fehler fehlschlägt, wenn ich insert into emp
SQL Developer oder SQL * Plus verwende:
CREATE OR REPLACE TRIGGER emp_bri
BEFORE INSERT ON emp
FOR EACH ROW
BEGIN
SELECT max(id) + 1 INTO :NEW.id FROM emp;
UPDATE emp SET salary = 5000;
END emp_bri;
Das Einfügen wird mit dem nächsten id
Wert erfolgreich abgeschlossen und aktualisiert alle emp
Datensätze. Ich verwende Oracle Database 11g Enterprise Edition Release 11.2.0.1.0. Ich habe über zusammengesetzte Trigger gelesen, aber das Beispiel verwendet sie nicht.
quelle
select max(id)
, um eindeutige Nummern zuzuweisen. Tu es einfach nicht. Es ist einfach falsch und wird nicht so gut skaliert.Antworten:
Es gibt eine Ausnahme. Wenn Sie einen
before insert
Trigger auf Zeilenebene für eine Tabelle definieren und eine einzelne Zeilenanweisung ausgebenINSERT
, wird dertable is mutating
Fehler nicht ausgelöst . Wenn Sie jedoch dieselbe Art von Trigger definieren und eine mehrzeiligeINSERT
Anweisung ausgeben , wird der Fehler ausgelöst . Hier ist ein Beispiel:Hier ist eine einzeilige
insert
Anweisung, die keinen mutierenden Tabellenfehler auslöst:Hier ist eine mehrzeilige Einfügeanweisung, die einen mutierenden Tabellenfehler auslöst:
quelle
ID 132569.1
(ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement
).