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

Ich habe einen Trigger, der autonom ist, aber nur einmal in derselben Sitzung ausgeführt wird

Sie verwenden eine autonome Transaktion, um die Tatsache zu umgehen, dass ein Trigger seine Tabelle nicht selbst abfragen kann. Sie sind auf den berüchtigten Mutating-Table-Fehler gestoßen und haben festgestellt, dass der Fehler verschwindet, wenn der Trigger als autonome Transaktion deklariert wird.

Kein Glück für Sie, das löst das Problem überhaupt nicht:

  • Erstens geht jegliche Transaktionslogik verloren. Sie können die Änderungen an suscription_fact nicht rückgängig machen Tabelle, sie sind engagiert , während Ihre Haupttransaktion dies nicht ist und rückgängig gemacht werden könnte. Sie haben also auch Ihre Datenintegrität verloren.
  • Der Auslöser kann die neue Zeile nicht sehen, da die neue Zeile noch nicht festgeschrieben wurde! Da der Trigger in einer unabhängigen Transaktion ausgeführt wird, kann er die nicht festgeschriebenen Änderungen der Haupttransaktion nicht sehen:Sie werden auf völlig falsche Ergebnisse stoßen.

Aus diesem Grund sollten Sie in autonomen Transaktionen niemals eine Geschäftslogik verwenden. (Es gibt legitime Anwendungen, aber sie beschränken sich fast ausschließlich auf das Protokollieren/Debuggen).

In Ihrem Fall sollten Sie entweder:

  1. Aktualisieren Sie Ihre Logik, sodass sie Ihre Tabelle nicht abfragen muss (Aktualisieren von suscription_fact nur wenn die neue Zeile aktueller ist als der alte Wert, der in id_date_unsuscription gespeichert ist ).
  2. Vergessen Sie die Verwendung von Geschäftslogik in Triggern und verwenden Sie ein Verfahren, das alle Tabellen korrekt aktualisiert, oder verwenden Sie eine Ansicht, da wir hier einen klaren Fall von redundanten Daten haben.
  3. Verwenden Sie einen Workaround, der tatsächlich funktioniert (von Tom Kyte) .

Ich würde dringend empfehlen, hier (2) zu verwenden. Verwenden Sie keine Trigger, um Geschäftslogik zu codieren. Sie sind schwer ohne Fehler zu schreiben und noch schwerer zu warten. Die Verwendung einer Prozedur garantiert, dass der gesamte relevante Code an einer Stelle gruppiert ist (ein Paket oder eine Prozedur), einfach zu lesen und zu befolgen und ohne unvorhergesehene Konsequenzen.