mixmastertobsi: MySql Änderung bei Update

Hallo,

gibt es bei MySQL die Möglichkeit die Änderungen bei UPDATE anzeigen zu lassen, so dass diese "geloggt" werden können.

Beispiel:

bestehender Datensatz

ID | ARTIKEL | PREIS 1 | Mütze Rot | 10

UPDATE artikel SET artikel='Mütze Rot', preis='5' WHERE ID='1'

Nun möchte ich, dass MYSQL erkennt, dass es nur bei der Spalte "Preis" eine Änderung gab und diese Änderung soll ausgegen werden, damit ich dokumentieren kann, was der Mitarbeiter an Änderungen in der Tabelle vorgenommen hat.

  1. Tach,

    Nun möchte ich, dass MYSQL erkennt, dass es nur bei der Spalte "Preis" eine Änderung gab und diese Änderung soll ausgegen werden, damit ich dokumentieren kann, was der Mitarbeiter an Änderungen in der Tabelle vorgenommen hat.

    ja, die ersten zwei Antworten in https://stackoverflow.com/questions/12563706/is-there-a-mysql-option-feature-to-track-history-of-changes-to-records erlauben das mitloggen aller Änderungen; was sich genau geändert hat, kannst du dann über Vergleiche der Versionen herausfinden.

    mfg
    Woodfighter

    1. Hallo und Danke. Sieht schon mal gut aus, aber kann ich hier auch noch dokumentieren lassen, welcher User die Änderung gemacht hat. Der Username ist als Cookie hinterlegt.

      1. Tach,

        Hallo und Danke. Sieht schon mal gut aus, aber kann ich hier auch noch dokumentieren lassen, welcher User die Änderung gemacht hat. Der Username ist als Cookie hinterlegt.

        ja, du musst dafür natürlich in jeder betroffenen Tabelle eine Spalte für den Usernamen anlegen und den dann jeweils mit ablegen.

        mfg
        Woodfighter

  2. Loggen (binlog) oder Trigger.

  3. Hallo

    vielleicht hilft dir ja folgendes:

    Ich hatte dies mal bei einem kleinen internen Projekt umgesetzt. Es ist eine Art History die in eine separate Tabelle geschrieben wird, jeweils bei einem Insert, Update und Delete. Dazu werden einfach jeweils drei Trigger angelegt.

    Beispiel ein Update Trigger

    BEGIN
    	DECLARE x INT;
    	SET x = (SELECT max(revision) FROM todohistory WHERE todoid = NEW.todoid) +1; 
    	IF(x IS NULL) THEN
            SET x = 1;
        END IF;
        INSERT INTO todohistory (`todoid`, `number`, `active`, `todohours`, `todostatus`, `tododescription`, `tododate`, `userid`, `changetimestamp`, `changetype`, `revision`)
        VALUES
        (NEW.todoid,NEW.number,NEW.active,NEW.todohours ,NEW.todostatus ,NEW.tododescription ,NEW.tododate ,NEW.userid ,NOW() ,'update',x);
        END
    

    viele Grüße hawk

    1. Hallo,

      Beispiel ein Update Trigger

      BEGIN
      	DECLARE x INT;
      	SET x = (SELECT max(revision) FROM todohistory WHERE todoid = NEW.todoid) +1; 
      	IF(x IS NULL) THEN
      

      Kann x hier tatsächlich NULL sein? Oder prüfst du hier auf einen Fall, der, wenn er denn eintritt, schon beim Versuch 1 zu addieren in der Zeile vorher einen Fehler schmeißt?

          SET x = 1;
      

      Falls NULL + 1 bereits das erwünschte 1 ergibt, erübrigt sich doch das IF?

      Gruß
      Kalk

      1. Tach,

        Falls NULL + 1 bereits das erwünschte 1 ergibt, erübrigt sich doch das IF?

        alle Arithmetik mit NULL als Operand ergibt NULL, alles andere wäre problematisch.

        mfg
        Woodfighter

      2. Hallo Kalk,

        ja du hast recht. Die kleinste "revisions" Nummer beginnt immer bei 1. Besser wäre dann vermutlich auf 0 Prüfung.

        Gruss hawk

  4. Hallo, ich habe es nun mal wie folgt gelöst, allerdings gibt es noch ein Problem. Ich möchte, dass NUR geloggt wird, wenn es auch wirklich eine Änderung gab. Aktuell ist es so, dass er auch loggt, auch wenn sich nichts geändert hat.

    DROP TRIGGER IF EXISTS auftrag_after_update;
    DELIMITER $$
    CREATE TRIGGER auftrag_after_update
    AFTER UPDATE ON auftrag
    FOR EACH ROW
    BEGIN
     INSERT INTO shop_logtable
       ( tabelle, tabelle_id, value, user )
     VALUES
       (   
       "auftrag",
       NEW.auftragnr,
       CONCAT(
       "UPDATE ",
    	 if( NEW.re_adr = OLD.re_adr, "", CONCAT( "re_adr=", "'", CAST( NEW.re_adr AS CHAR ), "'," ) ),
         if( NEW.li_adr = OLD.li_adr, "", CONCAT( "li_adr=", CAST( NEW.li_adr AS CHAR ), "," ) ),
       ),
       NEW.user
       );
    END $$
    DELIMITER ;
    
    1. Hallo

      Bitte benutze die Buttons oberhalb des Eingabefelds, bei Quelltext insbesondere „</>“. Bei mir kam der Versuch, aus deiner Eingabe eine Formel zu machen, heraus.

      Screenshot:

      Formel statt Code

      ich habe es nun mal wie folgt gelöst, allerdings gibt es noch ein Problem. Ich möchte, dass NUR geloggt wird, wenn es auch wirklich eine Änderung gab. Aktuell ist es so, dass er auch loggt, auch wenn sich nichts geändert hat.

      Das hast du ja auch so angewiesen. Schreibe nach jedem UPDATE eine Zeile in die Logtabelle. Vergleiche stattdessen erst die alten mit den neuen Werten, speichere die Tatsache, dass es eine Änderung gab in eine Variable und erzeuge den Eintrag nur dann, wenn die Variable es hergibt, es also tatsächlichen eine Änderung gab.

      Für die anderen Leser noch einmal dein Trigger (unverändert) in und mit Codeformatierung.

      DROP TRIGGER IF EXISTS auftrag_after_update;
      DELIMITER $$
      CREATE TRIGGER auftrag_after_update
      AFTER UPDATE ON auftrag
      FOR EACH ROW
      BEGIN
       INSERT INTO shop_logtable
         ( tabelle, tabelle_id, value, user )
       VALUES
         (   
         "auftrag",
         NEW.auftragnr,
         CONCAT(
         "UPDATE ",
      	 if( NEW.re_adr = OLD.re_adr, "", CONCAT( "re_adr=", "'", CAST( NEW.re_adr AS CHAR ), "'," ) ),
           if( NEW.li_adr = OLD.li_adr, "", CONCAT( "li_adr=", CAST( NEW.li_adr AS CHAR ), "," ) ),
         ),
         NEW.user
         );
      END $$
      DELIMITER ;
      

      Tschö, Auge

      --
      Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
      Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
      1. Hi,

        Bitte benutze die Buttons oberhalb des Eingabefelds, bei Quelltext insbesondere „</>“. Bei mir kam der Versuch, aus deiner Eingabe eine Formel zu machen, heraus.

        ja, eigentlich müsste jetzt Gunnar zur Stelle sein und motzen, dass Markdown für ein Forum wie dieses nicht geeignet ist. Und ich würde ihm schweigend zustimmen.

        Screenshot:

        Formel statt Code

        Und dabei dachte ich noch, ich hätte das schnell genug repariert. :-(

        So long,
         Martin

        1. Hallo Der Martin,

          Bitte benutze die Buttons oberhalb des Eingabefelds, bei Quelltext insbesondere „</>“. Bei mir kam der Versuch, aus deiner Eingabe eine Formel zu machen, heraus.

          ja, eigentlich müsste jetzt Gunnar zur Stelle sein und motzen, dass Markdown für ein Forum wie dieses nicht geeignet ist. Und ich würde ihm schweigend zustimmen.

          Du hättest zur Mitgliederversammlung kommen sollen.

          Bis demnächst
          Matthias

          --
          Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)