Trigger- Problen: wann kann man User_Objects auslesen ?

quinoman

Benutzer
Beiträge
5
Hallo,
bin neu hier und unter Zeitdruck. Falls ich etwas falsch mache hier, bitte ich um Nachsicht. Werde mich baldmöglichst in die hiesigen Gepflogenheiten einlesen. Meine Frage habe ich (nicht nur hier) recherchiert, leider ohne Erfolg.

Vorhaben: Ein Trigger soll protokollieren, wenn im Schema des Benutzers ein Objekt ertsellt wird.
Idee : Trigger soll den aktuellsten /neuesten Eintrag aus USER_OBJECTS auslesen, also den mit MAX(timestamp)

Code:
CREATE OR REPLACE TRIGGER newobj_trg
AFTER CREATE on SCHEMA
DECLARE v_objname user_objects.OBJECT_NAME%type;
BEGIN
SELECT OBJECT_NAME into v_objname from user_objects where timestamp = (select max(timestamp) from user_objects);
DBMS_OUTPUT.PUT_LINE('Erstellt ' || v_objname);
END;

Ich kann erfolgreich kompilieren und es klappt FAST. Leider gibt der Trigger immer das vorletzte Objekt aus, also:

TRIGGER NEWOBJ_TRG kompiliert
sql> create synonym SYN_1
Trigger-Meldung: Erstellt NEWOBJ_TRG

sql> create synonym SYN_2
Trigger-Meldung: Erstellt SYN_1

Wo ist der Denkfehler ? Wenn ich den Trigger abschalte und nach
sql> create synonym SYN_N
sofort einen SELECT auf USER_OBJECTS mache, dann steht SYN_N sehr wohl drinnen. Somit kann meine erste Vermutung , USER_OBJECTS würde erst später (z.B. nach einem impliziten Commit ) geschrieben, nicht der Grund sein.

Für Hilfe bedanke ich mich schon jetzt !!!

Gruss, der "Quinoman"
 
Werbung:
Vorhaben: Ein Trigger soll protokollieren, wenn im Schema des Benutzers ein Objekt ertsellt wird.
Idee : Trigger soll den aktuellsten /neuesten Eintrag aus USER_OBJECTS auslesen, also den mit MAX(timestamp)

Bin mit Oraggle nicht vertraut, kann also durchaus sein, daß ich Mist sage, aber: kannst Du nicht einen TRIGGER auf INSERT machen, auf einer Tabelle, die die Objekte enthält? In PostgreSQL wäre dies pg_class (wobei das in PG so nicht gehen würde weil das eine Systemtabelle ist und das nicht erlaubt ist, da einen TRIGGER zu definieren) Also, ich denke mal, nach Deiner Beschreibung, ein AFTER INSERT - Trigger auf USER_OBJECTS sollte es tun.
 
Vermutlich läuft der Trigger zeitlich nach dem CREATE SCHEMA aber vor dem INSERT in die Systemtabelle. Insofern könntest du, in dem Moment in dem der Trigger feuert, eventuell den Eintrag noch gar nicht in der Systemtabelle haben. Das würde ich mal testen in dem ich die ganze Systemtabelle einmal Hilfsweise ausgebe oder irgendwo hin kopiere.

Aber akretschmer sagt ja schon, ein INSERT Trigger auf die Systemtabelle liegt für mich auch auf der Hand.
 
Vielen Dank für die schnellen Antworten. Auf die Idee mit dem INSERT Trigger bin ich (obwohl blutiger Anfänger, bin erst seit gut 1 Woche in einem Kurs) auch gekommen. Aber USER_OBJECTS ist ein (komplexer) View, der nur einen INSTEAD OF Trigger zulassen würde. Auch der scheitert, manges Rechte - denn der View gehört SYS. Trotz umfangreicher GRANTS (als SYS grant ALL on user_objects to my_user erfolgreich erteilt) habe ich das nicht hinbekommen.
Der Hinweis, dass "in dem Moment in dem der Trigger feuert, eventuell den Eintrag noch gar nicht in der Systemtabelle (steht)." trifft es, denn genau so verhält der Trigger sich ja.

Mir wäre natürlich eine Lösung am liebsten, aber eine schlüssige Erklärung, WARUM das so ist, würde mir zumindest einen kleinen Lernerfolg verschaffen.
Also etwa, wenn Oracle explizit sagt, ".......ein Eintrag in USER_OBJECTS (bzw. auch ALL_OBJECTS) erfolgt erst wenn Aktion UND zugehörige Trigger erfolgreich waren"
Soetwas habe ich aber nirgends gefunden.
Schade, denn der Ansatz des Trigger war so schön simpel.......


Grüsse & schönes Wocheende, Quinoman
 
Zuletzt bearbeitet:
Dafür müsste ich dann auch Oracle kennen um solche Aussagen treffen zu können, dem ist aber nicht so. Vieleicht tut es auch ein Job der Einmal pro Minute prüft, ob ein neues Objekt vorliegt. Ist natürlich weit weniger elegant.
 
Danke. Klar, anders geht meistens, aber mir geht es ja in erster Linie um's Verstehen, wann und wie Trigger für solch eine Aufgabe geeignet sind. Ich kann natürlich auch eine Kopie der User_Objects zu einem Zeitpunkt X erstellen und dann zum Zeitpunkt Y rausfiltern, was dazu gekommen ist. Das beantwortet aber nicht die generelle Frage, WARUM ich mit meinem Ansatz gescheitert bin (selbst unser Tutor war verblüfft, dass es so nicht geht). Pragmatismus ist gut, aber etwas Wissen schadet auch nicht.
Ich werde weitersuchen :). Der Erste, der eine exakte Erklärung bzw. erfolgreiche Anpassung hat bekommt 10 Punkte !
Greets, Quinoman
 
Wenn Trigger auf Views gehen (ich hab das noch nie getestet) dann könnte man doch eine neue View auf USER_OBJECTS machen und darauf einen Trigger.
 
Hallo, nochmal DANKE an alle,die sich um Hilfe bemüht haben. Leider hilft mir das so nicht weiter. Wie gesagt, es geht in erster Linie NICHT darum, eien Alternative zu finden, sondern um das Verständnis, warum es SO NICHT geht. Ich habe eine STARKE Vermutung; nämlich, dass das Schreiben in USER_OBJECTS ebenfalls ein (interner, vom System bereitgestellter) Trigger ist und dieser eben erst nach Abschluß der Transaktion feuert, also NACH meinem Trigger. Ich versuche nun, dies mit Oracle-Experten und/oder Doku zu klären. Euch allen ein Dankw .... vom Quinoman
 
Werbung:
Wie gesagt, es geht in erster Linie NICHT darum, eien Alternative zu finden, sondern um das Verständnis, warum es SO NICHT geht.

Rein von der Logic her: ich würde solche System-Trigger generell IMMER nach allen User-Triggern feuern, weil Du sonst nicht wissen kannst, ob nicht doch ein User-Trigger fehlschlägt.
 
Zurück
Oben