Announcement

Collapse
No announcement yet.

Trigger

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Die Lösung ist ein After-Statement-Trigger. Diese Trigger unterliegen nicht der MT-Beschränckung.
    Aha.
    Code:
    SQL> create table t (id number);
    
    Tabelle wurde erstellt.
    
    SQL> create or replace trigger trg_t after update on t
      2  for each row
      3  declare
      4   x number;
      5  begin
      6   select count(*) into x from t;
      7  end;
      8  /
    
    Trigger wurde erstellt.
    
    SQL> insert into t values(123);
    
    1 Zeile wurde erstellt.
    
    SQL> insert into t values(456);
    
    1 Zeile wurde erstellt.
    
    SQL> commit;
    
    Transaktion mit COMMIT abgeschlossen.
    
    SQL> update t set id=3;
    update t set id=3
           *
    FEHLER in Zeile 1:
    ORA-04091: Tabelle DIMITRI.T wird gerade geändert, Trigger/Funktion sieht dies möglicherweise nicht
    ORA-06512: in "DIMITRI.TRG_T", Zeile 4
    ORA-04088: Fehler bei der Ausführung von Trigger 'DIMITRI.TRG_T'
    Leider gestatten sie keinen Zugriff mehr auf die :NEW und :OLD
    Auch diese Annahme ist falsch:
    Code:
    SQL> create or replace trigger trg_t after update on t
      2  for each row
      3  declare
      4   x number;
      5   y number;
      6  begin
      7    dbms_output.put_line('old='||:old.id);
      8    dbms_output.put_line('new='||:new.id);
      9   --select count(*) into x from t;
     10  end;
     11  /
    
    Trigger wurde erstellt.
    
    SQL> set serveroutput on
    
    SQL> update t set id=3;
    old=123
    new=3
    old=456
    new=3
    
    2 Zeilen wurden aktualisiert.
    Zum Rest: Man kann sicherlich eine einfache Prüfung beliebig kompliziert implementieren um doch irgendwie einen Trigger verwenden zu können. Man könnte es aber auch einfach richtig machen.

    Multiuser Betrieb ist hier übrigends auch noch nicht berücksichtigt.

    Dim

    [EDIT]Ok mein Fehler. Du hast von einem Statement Trigger gesprochen. Allerdings ist ein Statement Trigger generell nicht von MT betroffen. Egal ob BEFORE oder AFTER[/EDIT]
    Zuletzt editiert von dimitri; 28.05.2008, 08:48.
    Zitat Tom Kyte:
    I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

    Comment


    • #17
      Hallo Dim,

      offensichtlich reden wir hier etwas aneinander vorbei. Ich sprach von einem After-Statement-Trigger. Du verwendest in deinem Bsp. wieder einen For-Each-Row-Trigger. Ein Statement-Trigger ist eben nicht FOR EACH ROW.
      [highlight=sql]
      create or replace trigger trg_t after update on t
      declare
      x number;
      begin
      select count(*) into x from t;
      end;
      /
      [/highlight]

      Und in diesem Trigger kannst du nicht auf :NEW und :OLD zugreifen - kannst du gerne ausprobieren .

      Gruß Falk
      Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

      Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

      Comment


      • #18
        Ja ich habs vorher auch grade bemerkt. Siehe auch das [EDIT] in meinem Posting.

        Dim
        Zitat Tom Kyte:
        I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

        Comment


        • #19
          Originally posted by dimitri View Post
          Die Geschäftslogik muss in einer eigenen, dafür bestimmten Anwendungsschicht liegen. Ob das jetzt in einer PL/SQL Routine liegt oder in einem EJB ist meiner Meinung nach egal. Soweit stimmen wir wohl überein.
          Also wenn ich den Eingangspost richtig gelesen habe, geht es hier um die Durchsetzung bestimmter Regeln und nich um die Implementierung einer Logik. Für mich sind das zwei verschiedene paar Schuhe. Und zur Durchsetzung von Regeln gibt es neben Constraints eben auch Trigger.

          Originally posted by dimitri View Post
          Es gibt jedoch keinen Grund dies in einem Trigger abzulegen.
          Auf Anhieb fällt mir mindestens einer ein: Wenn ich sicherstellen muß, daß eine bestimmte Regel eingehalten wird und ich keine Möglichkeit habe die Anwendung zu ändern, dann kann ich hoch und runter springen ich werde einen Trigger dafür einsetzen müssen.

          Originally posted by dimitri View Post
          ...und es steigt die Versuchung Datenbankfunktionalitäten "nachzuprogrammieren" (hab erst letztens wieder einen Trigger gesehen der RI nachgebildet hat).
          Das kennen wir ja zur Genüge, weil Dinge mißbraucht werden KÖNNTEN, werden sie verboten oder abgeschafft

          Originally posted by dimitri View Post
          Seit Jahrzehnten stellen Programme Schnittstellen und entsprechende Prüfungen bereit, die nachvollziehbar bestimmte Bedingungen prüfen und ggf. darauf reagieren. Denn Sinn und Zweck dies jetzt plötzlich in Trigger zu verlagern versteh ich nicht.
          Ein Trigger ist neben dem Constraint der "kleinste gemeinsame Nenner", an dem alle Zugriffe auf eine Tabelle vorbei müssen.
          Für komplette Neuentwicklungen gebe ich dir vollkommen recht, daß man diesen KGN sehr viel weiter oben ansiedeln kann, aber für gewachsene Strukturen aus Datenbank, alter und neuer Anwendung, sowie diversen Erweiterungen muß man manchmal sehr weit nach unten.

          Originally posted by dimitri View Post
          Er zeigt dir, dass Du etwas gemacht has was deine Datenintegrität verletzten kann. Ich halte das durchaus für fehlerhaftes Design.
          Ok, es ist unstrittig ein Fehler, ein Programmierfehler, ein sehr grober sogar, aber deshalb ist doch nicht das gesamte Anwendungsdesign Schrott
          Ich hab doch kein vermurkstes Haus, nur weil im Bad kein Fenster ist.

          Originally posted by dimitri View Post
          Ein ORA-04091 ist ein Runtimefehler. Ähnlich wie eine Nullpointer Exception sagt mir das, dass irgendwo ein Hund drinnen ist.
          Ist die Nullpointer Exception dann ein Zeichen für fehlerhaftes Anwendungsdesign?

          Originally posted by dimitri View Post
          ...und dazu gehört eben auch, dass man darauf hingewiesen wird das man auf dem Holzweg ist.
          Das sehe ich genauso.

          Originally posted by dimitri View Post
          Eine gangbare Alternative hat er ja bekommen (ebenso den Hinweis, dass sein INSERT-Trigger einen kleinen aber nicht unerheblichen Bug hat - wer kriegts raus welchen? )
          Nach deiner Definition für fehlerhaftes Anwendungsdesign bin ich mir nicht sicher, was bei dir ein "nicht unerheblicher Bug" ist. Hier solltest du uns besser aufklären.

          @TitoTatonka: Sorry für die OffTopic-Diskussion, die dich in keinster Weise weiterbringt.

          Gruß Falk
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment


          • #20
            @tito
            bei einem Insert ist FALLNUM = :new.FALLNUM immer FALSE oder ist FALLNUM nicht UNIQUE

            @Falk
            dein letzter Post gehört doch in eine PM. Zumal ich glaube tito versteht nicht was du meinst.

            Comment


            • #21
              und ich keine Möglichkeit habe die Anwendung zu ändern, dann kann ich hoch und runter springen ich werde einen Trigger dafür einsetzen müssen.
              Ok. Da hast Du recht. Mea culpa. Allerdings sollte das der letzte Weg sein wenn alles andere nicht funktioniert und nicht der erste und bevorzugte.

              Das kennen wir ja zur Genüge, weil Dinge mißbraucht werden KÖNNTEN, werden sie verboten oder abgeschafft
              Nein Trigger haben durchaus ihre Berechtigungen. Historisierungsdaten wegschreiben, technische Felder setzen (z.B. einen Änderungstimestamp) oder das gute alte Erzeugen eines PKs aus einer Sequenze. Aber eben keine fachliche Logik oder "fachliche Constraints" (mal von der obigen Krux abgesehen).
              Das sollte man auch einem Einsteiger so erklären.

              hier solltest du uns besser aufklären.
              Uminky hat es gesehen. Beim ersten Insert eines bisher nicht vorhandenen Falls (FALLNUM ) liefern die Abfragen
              Code:
              SELECT MAX(DIAGNOSE_STATUS) INTO x
              FROM DIAGNOSE
              WHERE FALLNUM = :new.FALLNUM;
              SELECT MAX(TERMIN) INTO y
              FROM DIAGNOSE
              WHERE FALLNUM = :new.FALLNUM;
              jeweils NULL. Im späteren IF wird die Bedingung dann nie erfüllt sein, was wiederum dazu führt, das DIAGNOSE_STATUS jeden Wert annehmen kann:
              Code:
              IF :new.DIAGNOSE_STATUS <= x OR :new.TERMIN <= y THEN
              RAISE_APPLICATION_ERROR(-20000,'Falsche Eingabe');
              END IF;
              Ist aber erstmal ein falscher DIAGNOSE_STATUS in der Tabelle, können auch die restlichen Prüfungen nicht mehr korrekt laufen.

              Dim
              Zitat Tom Kyte:
              I have a simple philosophy when it comes to the Oracle Database: you can treat it as a black box and just stick data into it, or you can understand how it works and exploit it as a powerful computing environment.

              Comment

              Working...
              X