Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Trigger- Problen: wann kann man User_Objects auslesen ?

Dieses Thema im Forum "Oracle" wurde erstellt von quinoman, 25 Juli 2014.

  1. quinoman

    quinoman Benutzer

    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"
     
  2. akretschmer

    akretschmer Datenbank-Guru

    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.
     
  3. ukulele

    ukulele Datenbank-Guru

    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.
     
  4. quinoman

    quinoman Benutzer

    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: 25 Juli 2014
  5. ukulele

    ukulele Datenbank-Guru

    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.
     
  6. quinoman

    quinoman Benutzer

    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
     
  7. ukulele

    ukulele Datenbank-Guru

    Ohne Oracle System kann ich dir dabei leider nicht helfen :)
     
  8. akretschmer

    akretschmer Datenbank-Guru

  9. ukulele

    ukulele Datenbank-Guru

    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.
     
  10. quinoman

    quinoman Benutzer

     
  11. quinoman

    quinoman Benutzer

    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
     
  12. akretschmer

    akretschmer Datenbank-Guru

    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.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden