Announcement

Collapse
No announcement yet.

Triggerproblem

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

  • Triggerproblem

    Hi!

    Ich habe ein Problem und bin leider mit Hilfe von Google nicht ans Ziel gekommen. Ich hoffe sehr dass mir von euch jemand helfen kann!

    Bei einem unserer Kunden ist eine Oracle 10g DB im Einsatz, darauf läuft auch die Datenbank für unsere Anwendung. Bisher wurde das Programm lokal installiert, nun soll es über Citrix eingestzt werden.

    Bei einer lokalen Installation wurde in unserer Datenbank in der Tabelle "Arbeitsplatz" dieser eingetragen (Name, Installverzeichnis, Lizenzart)
    Greift ein PC ohne dass auf diesem installiert wurde (z.B. Programmverzeichnis und Registry einträge wurden kopiert) auf die Datenbank zu wird er in der Tabelle "Arbeitsplatz" mit der niedrigsten Lizenzstufe eingetragen, der Anwender darf also praktisch gar nichts. Dies geschiet dementsprechend auch ein Benuter das Programm über Citrix aufruft. Allerdings hat dieser Kunde nun eine Hauslizenz erworben und jeder PC der sich einträgt soll eine höre Lizenzstufe erhalten. Dies wollte ich "einfach" mit einem Trigger machen, der so aussehen sollte:

    CREATE OR REPLACE TRIGGER "USERX"."LIZENZUPDATE"
    AFTER INSERT ON "ARBEITSPLATZ"
    REFERENCING NEW AS newRow
    FOR EACH ROW
    WHEN (newRow."LizenzVerwendung" = '1')
    BEGIN
    UPDATE USERX.ARBEITSPLATZ SET "LizenzVerwendung" = '2'
    WHERE "LizenzVerwendung" = '1';
    END;

    Leider fliegt mir das Ding um die Ohren! Wenn das Programm aufgerufen wird kommt die Fehlermeldung:

    Fehlermeldung: Run-time error '-2147217900 (80040e14)'

    ORA-04091: Tabelle USERX.ARBEITSPLATZ wird gerade geändert, Trigger sieht dies möglicherweise nicht.
    ORA-06512: "USERX.LIZENZUPDATE", Zeile 2
    ORA-04088: Fehler bei der Ausführung von Trigger 'USERX.LIZENZUPDATE'

    Das interessante daran ist, dass wenn ich das AFTER mit einem BEFORE ersetze läuft er. Aber das bringt eben nichts, da bei einer neuen Anmeldung am Server dann die Lizenzstufe 1 für diesen Arbeitsplatz bestehen bleibt!

    Bin mal gespannt was ihr dazu meint. Danke schonmal!

    Gruß
    Mika

  • #2
    Leider fliegt mir das Ding um die Ohren!
    Das ist auch absolut richtig. Oracle erlaubt nicht, dass Du in die Transaktion selbst hineinsiehst und dort Daten änderst, die eigentlich in dieser Form nie öffentlich existieren.

    Für das was Du machen möchtest gibt es einen viel besseren und korrekten Weg:
    Code:
    IF newRow.LizenzVerwendung='1' THEN
       newRow.LizenzVerwendung:='2';
    END IF;
    Das ganze in einen BEFORE Trigger und fertig.

    Dies wollte ich "einfach" mit einem Trigger machen, der so aussehen sollte
    Wirklich ideal ist das aber auch nicht, denn Trigger werden vergessen, können abgeschaltet werden etc. Es passiert einfach etwas magisches. Technisch mag es laufen, aber das Applikationsdesign wird unübersichtlicher und schwerer Wartbar wenn man fachliche Logik in Triggern ablegt. Sofern es keine andere Möglichkeit gibt, rate ich Dir dringend dazu diese "Lizenzmagie" gut zu dokumentieren.

    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


    • #3
      Erstmal Danke für die schnelle Antwort! Deine Antwort klingt auch einleuchtend, allerdings komm ich mit der Lösung noch nicht ganz klar. Sollte das dann so aussehen?

      CREATE OR REPLACE TRIGGER "USERX"."LIZENZUPDATE"
      BEFORE INSERT ON "ARBEITSPLATZ"
      REFERENCING NEW AS newRow
      FOR EACH ROW
      BEGIN
      IF newRow."LizenzVerwendung" = '1' THEN
      newRow."LizenzVerwendung" := '2';
      END IF;
      END;
      /

      Denn da kommt beim kompilieren die Meldung:
      Zeilen-# = 2 Spalten-# = 1 Fehlertext = PL/SQL: Statement ignored
      Zeilen-# = 2 Spalten-# = 4 Fehlertext = PLS-00201: Bezeichner 'NEWROW.LizenzVerwendung' muss deklariert werden

      Tut mir leid für die (vermutlich) grausigen Fehler

      Comment


      • #4
        Da hab ich doch glatt den : vor newrow vergessen.

        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


        • #5
          Wenn du einfach einmal den ganzen Trigger aufschreiben könntest wäre ich dir sehr zu Dank verpflichtet!

          Comment


          • #6
            Dann machen wir es gleich richtig:

            Code:
            CREATE OR REPLACE TRIGGER USERX.LIZENZUPDATE
            BEFORE INSERT ON ARBEITSPLATZ
            FOR EACH ROW
            BEGIN
              IF :new.LizenzVerwendung = '1' THEN
                :new.LizenzVerwendung := '2';
              END IF;
            END;
            /
            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


            • #7
              Beim ersten Aufruf des Programms wird dieses immer noch mit der niedrigsten geöffnet, aber der Eintrag ist korrekt. Beim 2. öffnen ist dann alles wie es sein soll. Etwas merkwürdig, aber das stellt kein Problem dar!

              Vielen Dank für die schnelle Hilfe Dimitri!!

              Comment

              Working...
              X