Announcement

Collapse
No announcement yet.

[erledigt] Trigger arbeitet nicht

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

  • [erledigt] Trigger arbeitet nicht

    Ich baue eine Stored Procedure, um automatisch neue Datensätze zu speichern:
    Code:
          /* vorläufige Speicherung der neuen Rechnung */
          insert into fibu.bk_bill (kd_id) values (last_kd);
          select last_insert_id() into last_id;
    Die anderen Felder in der Tabelle fibu.bk_bill sind (neben ID als auto-increment) entweder not null, haben einen default-Wert oder sollten durch einen Trigger "Before Insert for each row" festgelegt werden, beispielsweise:
    Code:
      if new.re_jahr is null
      then 
        set new.re_jahr = current_year;
      end if;
    Aber das funktioniert so nicht.
    Error Code: 1364. Field 're_jahr' doesn't have a default value
    Könnte es sein, dass ein Trigger nicht ausgelöst wird, wenn der INSERT aus einer Stored Procedure aufgerufen wird? Die Beschreibung über Restrictions on Stored Programs verstehe ich nicht (so weit reichen meine Englisch-Kenntnisse nicht). Danke schon mal! Jürgen

    Umgebung: MySQL Ver 8.42 Distrib 5.5.27, for Win64 on x86; MySQL Workbench CE for Windows version 5.2.42 revision 9752; Windows 7 Home Premium 64-bit

    PS. Die Unsicherheiten bei last_insert_id stören mich nicht.

    PS 2. current_year ist falsch, das gibt es nicht, sondern muss durch year(current_date) ersetzt werden.

    Nachtrag: Inzwischen habe ich festgestellt, dass das Problem wohl nicht an der SP liegt, sondern an der Workbench oder vielleicht sogar an MySQL selbst. Wenn ich bei "Edit Table" einen neuen Datensatz eintrage und mit Apply speichern will, werden fehlende Einträge in Spalten angemeckert, obwohl sie durch den Trigger mit Inhalt versehen werden sollen.

    Meine Frage lautet jetzt: Kann das jemand bestätigen? Ist es ein Problem der Workbench oder von MySQL? Wo kann man ein solches Verhalten als Bug melden (denn wozu gibt es sonst Trigger)?
    Zuletzt editiert von Jürgen Thomas; 08.10.2012, 13:56. Reason: Thema angepasst, es hat nichts mit SP oder Workbench zu tun.

  • #2
    Hast Du mal versucht, das in der mysql console / DOS box nachzuvollziehen?
    Hast Du überprüft, ob der Trigger a) fehlerfrei ist und b) aktiv (enable/disable)?

    Ein Trigger sollte dem Wesen nach bedingungslos ausgeführt werden. Dafür ist er da, vielleicht gibt es Ausnahmen in mysql, ich würde aber erstmal das naheliegende prüfen, dazu gehört vor allem: Sind die Datenbankobjekte tatsächlich so definiert, wie erwartet, geglaubt.
    Da Du weder Table Create statment noch Triggersourcen anführst, kann man dazu weiter wenig sagen.
    Gruß, defo

    Comment


    • #3
      OK, das Naheliegende hat mich nicht weiter gebracht. Die Tabellen-Definition (aus der Workbench kopiert und auf die problematischen Felder reduziert):
      Code:
      CREATE TABLE `bk_bill` (
        `ID` int(11) NOT NULL AUTO_INCREMENT,
        `re_jahr` int(11) NOT NULL,
        `re_datum` date NOT NULL,
        `kd_id` int(11) NOT NULL,
        PRIMARY KEY (`ID`),
      ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
      Dazu die Trigger-Definition:
      Code:
      CREATE DEFINER=`jt`@`localhost`
      TRIGGER `fibu`.`bk_bill_insert`
      BEFORE INSERT ON `fibu`.`bk_bill` FOR EACH ROW
      begin
        if new.re_jahr is null
        then 
          set new.re_jahr = year(current_date);
        end if;
        if new.re_datum is null
        then set new.re_datum = current_date;
        end if;
      end
      Dann ein Datensatz eingegeben (sowohl in der Workbench als auch in der CMD-Box, angemeldet jeweils als jt@localhost):
      Code:
      insert into fibu.bk_bill (kd_id) values (1);
      In beiden Fällen gibt es die Fehlermeldung:
      ERROR 1364 (HY000): Field 're_jahr' doesn't have a default value
      Ich finde in der Tabelle information_schema.triggers keine Einstellung, dass der Trigger deaktiviert sein könnte. Sollte es irgendwo bei der Datenbank oder der Engine (INNODB) eine Einstellung dazu geben, die mir bisher entgangen ist? Immerhin ist damit geklärt, dass es nichts mit Workbench oder SPs zu tun hat; aber womit sonst? Gruß Jürgen

      Comment


      • #4
        Tja, da gibt's wohl (noch) kein enable / disable. Sorry, ich war im Oracle modus.

        Aber Dein Problem könnte mit Restricted Mode bzw mit der Mysql Version zusammen hängen. Siehe Bug Bug #6295 in Version 5.0, 5.1.
        Falls das zutrifft für Dich, entweder aktuelle MySQL Version nehmen,
        Default vergeben,
        vielleicht hilft auch sql_mode mit NO_ZERO_DATE oder so, ist aber eher nicht empfehlenswert.

        Je nach SQL_MODE kannst Du auch Deinen Trigger abwandelln oder testen, was er überhaupt macht.
        Also z.B. If Then weglassen, dann ist wenigstens klar, ob er was einfügt / aktiv ist.
        Ansonsten die Bedingung evtl aufweichen, statt
        Code:
        if new.re_jahr is null
        z.B.
        Code:
        if new.re_jahr is null or new.re_jahr =0
        Ich bin kein mySQL Experte, die könnten sicher mehr dazu sagen.
        Gruß, defo

        Comment


        • #5
          Hallo,

          am Trigger liegt das nicht, sondern eher daran, wie (bzw. in welcher Reihenfolge) MySQL Constraints prüft. Der Trigger wird nicht ausgeführt, weil die NOT NULL Prüfung sehr viel Restrikter ist und das Statement bereits VOR dem BEFORE INSERT scheitern lässt. Abhilfe wäre hier die Definition der fraglichen Felder als NULLABLE, bzw. die Vergabe definierter Default-Werte, die dann im Trigger statt der Prüfung auf NULL abgefragt werden.
          z.B.:
          [highlight=sql]
          CREATE TABLE `bk_bill` (
          `ID` int(11) NOT NULL AUTO_INCREMENT,
          `re_jahr` int(11) NOT NULL DEFAULT 0,
          `re_datum` date NOT NULL DEFAULT '0000-01-01',
          `kd_id` int(11) NOT NULL
          PRIMARY KEY (`ID`)
          )
          ...
          CREATE TRIGGER `bk_bill_insert`
          BEFORE INSERT ON `bk_bill` FOR EACH ROW
          begin
          if new.re_jahr = 0
          then
          set new.re_jahr = year(current_date());
          end if;
          if new.re_datum = '0000-01-01'
          then set new.re_datum = current_date();
          end if;
          end
          [/highlight]

          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


          • #6
            Hallo Falk, danke vielmals für diesen Hinweis. Habe ich das in der Dokumentation überlesen, oder lernt man das erst nach jahrelanger intensiver Beschäftigung mit MySQL? Bei Firebird hatte ich mir genau diese Arbeitsweise angeeignet (NOT NULL und Werte durch Trigger zuweisen), aber für LibreOffice war eine neue MySQL-Datenbank der einfachste Weg. Dann werde ich deinem Vorschlag folgen (NOT NULL, 0 als Vorgabewert mit Trigger). Gruß Jürgen

            Comment


            • #7
              Das Verhalten ist nicht unbedingt "Standard". Es ist als Bug / Änderungswunsch gelistet. Hatte ich oben unter Bug #6295 drauf hingewiesen.
              http://bugs.mysql.com/bug.php?id=6295
              Gruß, defo

              Comment


              • #8
                Originally posted by defo View Post
                Das Verhalten ist nicht unbedingt "Standard".
                Nun ja, wie weit berücksichtigen die DBMS den SQL-Standard schon als ihren eigenen Standard...

                Es ist als Bug / Änderungswunsch gelistet. Hatte ich oben unter Bug #6295 drauf hingewiesen. http://bugs.mysql.com/bug.php?id=6295
                Sorry, da ich 5.5 benutze, hatte ich nach einem Bug von 2004 nicht gesucht. Mal sehen, ob es in weiteren acht Jahren möglich ist. Jürgen

                PS. Ich habe bei diesem Bug einen Kommentar hinzugefügt, vielleicht hilft es irgendwann einmal.
                Zuletzt editiert von Jürgen Thomas; 08.10.2012, 20:09. Reason: PS

                Comment

                Working...
                X