Horst Meier: Trigger Verständinsproblem

HI ich möchte in meiner Datenbank einen Trigger anlegen der nach einem INSERT auf eine Tabelle X ausgeführt wird.

Dieser Trigger soll nach dem INSERT in Tabelle X eine bestimmte Spalte updaten. Nur sagt mir mysql das die Tabelle bereits in Verwendung ist.

Welche Möglichkteiten habe ich das Problem zu umgehen? Ich würde gerne das update automatisiert durchführen lassen, so dass ein Programmierer sich nicht mehr darum kümmern muß und die DB immmer konsistent ist.

  1. Hello Horst,

    es ist für uns leichter, Dir zu helfen, wenn Du das Create-Statement der Tabelle, das Insertstatement und das Create Trigger Statement postest, so wie DU sie bisher vorliegen hast.

    Ohne diese Angaben bleibt es doch nur Rätselraten.

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Ok dann versuche ich das Problem mal etwas umfangreicher zu umreissen.

      Ich ahbe eine Tabelle in der ich eine Baumstruktur mit Hilfe des NestedSet Konzeptes abgelegt habe. Das Ganze sieht dann so aus:

      ---------------------------------------------------
      | tree_id(INT) | lft(INT) | rgt(INT) | depth(INT) |
      ---------------------------------------------------

      Nun möchte ich nachdem ein neuer Konten eingefügt wurde, automatisch dessen (Level-)Tiefe einfügen. Das Gleiche soll auch passieren, wenn ein Konten verschoben wurde. Da sich im letzteren Fall die Änderungen auf den ganzen Baum auswirken können, möchte ich einen Trigger oder eine Procedure haben mit der ich direkt auf der Datenbank arbeiten kann, ohne dass ich in PHP jede Updateanweisung einzeln ausführen muß.

      Ich habe auch schon versucht eine Updateanweisung für die gesamte DB zu formulieren, bin aber zu keinem Ergebnis gekommen.

      Hier mal das Query zum herausfinden welche Leveltiefe ein Knoten hat:

      SELECT n1.tree_id, COUNT(*) AS level
      FROM strukturAS n1, struktur AS n2
      WHERE n1.lft BETWEEN n2.lft AND n2.rgt
      GROUP BY n1.lft;

      NUn möchte ich daraus eine Updateanweisung machen die über die gesamte Tabelle geht. Am besten als Trigger. Aber auch als Procedure oder als einzelne SQL Anweisung würde mir schon weiterhelfen.

      1. Hi!

        Ich ahbe eine Tabelle in der ich eine Baumstruktur mit Hilfe des NestedSet Konzeptes abgelegt habe.
        Nun möchte ich nachdem ein neuer Konten eingefügt wurde, automatisch dessen (Level-)Tiefe einfügen. Das Gleiche soll auch passieren, wenn ein Konten verschoben wurde. [...]

        Da würde ich keinen Trigger nehmen, sondern zumindest die schreibenden Zugriffe komplett in Stored Procedures kapseln. Damit sollte nach meinem Verständnis auch das Bereits-Verwendet-Problem gar nicht erst auftreten.

        Lo!

        1. Hello,

          Da würde ich keinen Trigger nehmen, sondern zumindest die schreibenden Zugriffe komplett in Stored Procedures kapseln. Damit sollte nach meinem Verständnis auch das Bereits-Verwendet-Problem gar nicht erst auftreten.

          Stored Procedures haben mWn aber bei MySQL noch nichts mit der Kapselung der darin ausgeführten Statements zu tun. Das muss man explizit noch z.B. durch ein Table Lock berücksichtigen.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hello,

            Stored Procedures haben mWn aber bei MySQL noch nichts mit der Kapselung der darin ausgeführten Statements zu tun. Das muss man explizit noch z.B. durch ein Table Lock berücksichtigen.

            Gemeint war die Bindung der Statements zu einem atomar gekapselten Vorgang...

            An die einzelnen Statements kommt der User natürlich nicht heran.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
          2. Hi!

            Da würde ich keinen Trigger nehmen, sondern zumindest die schreibenden Zugriffe komplett in Stored Procedures kapseln. Damit sollte nach meinem Verständnis auch das Bereits-Verwendet-Problem gar nicht erst auftreten.

            Stored Procedures haben mWn aber bei MySQL noch nichts mit der Kapselung der darin ausgeführten Statements zu tun. Das muss man explizit noch z.B. durch ein Table Lock berücksichtigen.

            Eine Kapselung ist durch die SP schon vorhanden, aber nicht zwingend eine Atomarisierung. Das jedenfalls ist ein gutes Stichwort und sollte nicht unbeachtet bleiben.

            Was ich jedenfalls meinte: In der SP werden die Insert/Update-Statements nacheinander ausgeführt. Der Trigger läuft jedoch, während das eigentliche Insert/Update noch aktiv ist, und sperrt somit die Tabelle. Was jedoch gehen müsste, ist, den gerade bearbeiteten Datensatz zu verändern. Dazu muss man mit NEW.feldname hantieren und darf kein vollständiges UPDATE-Statement absetzen.

            Lo!

            1. Hello,

              Was ich jedenfalls meinte: In der SP werden die Insert/Update-Statements nacheinander ausgeführt. Der Trigger läuft jedoch, während das eigentliche Insert/Update noch aktiv ist, und sperrt somit die Tabelle. Was jedoch gehen müsste, ist, den gerade bearbeiteten Datensatz zu verändern. Dazu muss man mit NEW.feldname hantieren und darf kein vollständiges UPDATE-Statement absetzen.

              Wenn der Trigger wirklich die Tabelle sperren würde, wäre das ja schon der richtige Weg. Aber genaus _das_ funktioniert mWn bei MySQL noch nicht. Die Trigger sind dort noch nebenläufig. Sowie in einen Trigger verzweigt wird, ist die Tabelle wieder offen.

              Wie gesagt, ich habe das bisher auch nicht überprüfen können, nur schon viel im Web darüber gelesen.

              Ich experimentiere mit den MySQL-Triggern schon eine ganze Weile herum. Was mir immer noch fehlt ist, eine gezielte Exception werfen zu können. Das mache ich bisher immer noch durch eine Schmuddel-Funktion, die einfach eine nicht vorhandene Spalte anspricht. damit failt das Statement und damit der Trigger. Der gefakte Spaltenname ist dann sozusagen der Rückgabewert...

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de