Announcement

Collapse
No announcement yet.

Firebird - undo, rückgängig Funktion

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

  • Firebird - undo, rückgängig Funktion

    Hallo,

    ich habe das Problem, dass ich ein Programm mit einer Datenbank habe. Nun sollen die letzten Änderungen auf einer Firebird-Datenbank rückgängig gemacht werden können, natürlich per Klick auf einen Button im Programm.

    Das soll z.B. so ablaufen:

    1. Ich legen einen Datensatz an.
    2. Ich lösche einen Datensatz.
    3. Ich legen einen Datensatz an.
    usw.
    4. Zurück-Button gedrückt
    5. Zurück-Button gedrückt


    Wie kann ich die Aktionen auf der Datenbank von der letzten beginnend rückgängig machen?
    Gibt es dafür eine Funktion in der DB, die mir dabei hilf einen gewissen Status von Tabellen oder der ganzen Datenbank zu sichern und herzustellen?

    Danke für die Info.



    firebird, undo, rückgängig

  • #2
    Das kannst Du implementieren, in dem Du Savepoints verwendest und bei jedem Zurück einen Rollback To Savepoint xyz machst.

    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
      Hallo dimitri,

      danke für die Antwort. Was Du schreibst stimmt, aber nur innerhalb einer Transaktion.

      Das Anlegen und entfernen der einzelnen Datensätze erfolgt in einzelnen Transaktionen. Man stelle sich hierfür Programm mit eine Eingabemaske vor, wo immer ein Datensatz angelegt wird. In diesem Fall wird beim Löschen auch immer ein Datensatz DB-anfrage gelöscht.

      Unter diesen Voraussetzungen, d.h. nach Absenden des "Commit;" funktioniert der Savepoint nicht mehr.

      Comment


      • #4
        In diesem Fall musst Du dir merken, welche Daten (Tabelle, PK, DMLTyp) geändert wurden.

        Bei einem Insert ist es noch recht einfach, aber damit auch ein UPDATE/DELETE rückgängig gemacht werden kann, musst Du dir vor der Änderung des Satzes diesen in eine dafür vorgesehende Historisierungstabelle schreiben, ihm eine ID mitgeben, damit Du bei mehrfachen Änderungen auf diesen Satz nicht durcheinander kommst und diese ID mit deiner Änderungshistorie verknüpfen.

        Klickt der user auf Rückgängig liest Du anhand deiner Änderungshistorie aus, welche Tabelle betroffen ist, gehst mit der ID auf die Historierungstabelle, generierst einen INSERT oder UPDATE und machst die Änderung somit wieder rückgängig.

        Das ist alles recht aufwändig und zieht einiges an Entwicklungs- und Testaufwand nach sich.

        Interessant wird es auch, wenn ein User U1 Daten ändert, in die Mittagspause geht und ein anderer User U2 ändert jetzt die gleichen Daten nochmal. Würde U1 jetzt auf Rückgängig klicken macht er auch die Änderung von U2 rückgängig ohne gesehen zu haben, was dort überhaupt stand. 3 mal darfst Du raten, wer dann schuld ist, dass dieses blöde Programm Daten nicht übernimmt (ein Tipp es ist nicht U1 oder U2).

        Um das zu verhindern müsste man in alle Tabellen einen Timestamp oder laufende Nummer aufnehmen (falls nicht schon vorhanden wg. Optimistischem Locking) und sich in der Historisierungstabelle auch den TS merken, der mit den neuen Daten eingetragen wurde. Möchte man ein undo ausführen vergleicht man diesen TS mit der in der echten Tabelle und bricht ab, falls diese nicht übereinstimmen.

        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
          IB LogManager (http://www.upscene.com) bietet dir im Wesentlichen alles, was du für die Historisierung benötigst. Bei einem Undo geht es dann darum, die protokollierten Operationen von einem Zeitpunkt A bis B in absteigender Reihenfolge der Historisierung zu negieren und dann auszuführen. Negieren heisst, aus einer protokollierten DELETE Anweisung wird dann ein INSERT etc.

          Wichtig ist hier, dass du bei der Historisierung alle alten/neuen Spaltenwerten auch mitspeicherst, da du dann sonst z.B. aus einem DELETE kein INSERT machen kannst. So auch bei einem UPDATE wo die "neuen" mit den alten Werten überschrieben werden müssen.

          lg,
          Tom
          Thomas Steinmaurer

          Firebird Foundation Committee Member
          Upscene Productions - Database Tools for Developers
          Mein Blog

          Comment

          Working...
          X