Announcement

Collapse
No announcement yet.

Letzte Änderung in einer Firebird Tabelle (Systemtabelle ?)

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

  • Letzte Änderung in einer Firebird Tabelle (Systemtabelle ?)

    Hallo,

    ich habe folgendes Problem:
    Durch ein Programm wird eine Firebird-Tabelle komplett gelöscht und anschließend mit neuen Datenätzen gefüllt.

    Anschließend werden auf diese Tabelle Auswertungen gemacht. Um zu wissen, von welchem Stand (Datum+Uhrzeit) die Tabelle ist, würde ich gerne auf die Systeminformation zugreifen, die vermutlich in einer internen RDB-Tabelle abgelegt ist.

    Wenn ja, wie greife ich auf diese Information zu bzw. wie heißt diese Tabelle ? Läßt sich auch der User angeben, der die letzte Datensatzänderung hervorgerufen hat ?

    Grüsse,
    Carsten

    P.S.: Lassen sich diese Informationen auch in "IBExpert" anzeigen ?

  • #2
    Hallo Carsten,
    <br><br>
    das letzte Änderungsdatum einer Tabelle wird intern (=Systemtabelle) nirgends mitgspeichert. Am besten wird sein, dass Du Dir das selbst über Trigger realisierst.
    <br><br>
    Thoma
    Thomas Steinmaurer

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

    Comment


    • #3
      Hallo noch mal eine kurze Zusatzerklärung:
      Bei Paradox konnte ich früher den Zeitstempel der entsprechenden "db"-Datei nutzen, um zu wissen, von welchem Zeitpunkt die Datei war.

      Gibt es etwas ähnliches bei Firebird oder wie gehe ich am sinnvollsten vor ?

      Grüsse,
      Carste

      Comment


      • #4
        Hi Thomas,

        da hat sich unsere Antwort ja überschnitten.

        Das mit den Triggern halte ich aus folgendem Grund für meine Anwendung nicht geeignet, sei denn Du belehrst mich mal wieder eines besseren )

        Also, die Firebird-Tabelle "Tab1" wird nach Klick auf einen Button im Client-Programm gelöscht und anschließend werden ca. 200-400 Datensätze in "Tab1" neu eingetragen. Es wäre doch ineffektiv, wenn der Trigger auch ca. 200-400 mal angestoßen wird, oder ?

        Da das letzte Änderungsdatum intern (=Systemtabelle) nirgends mitgespeichert wird, würde ich bisher als beste Möglichkeit ansehen, die letzte Änderung vom Client-Programm in die Datenbank (z.B. Tab2) eintragen zu lassen.

        Grüsse,
        Carste

        Comment


        • #5
          Hallo Carsten,<br><br>
          ein nettes Beispiel, wo sogenannte Statement-Level Trigger wieder Sinn machen würden. ;-)
          <br><br>
          Du hast natürlich recht, der Trigger wird für jeden geänderten Datensatz aufgerufen. D.h., wenn Du damit leben kannst, dass das Setzen des Zeitstempels in der Client-Anwendung passiert, dann spricht nichts dagegen es dort zu machen. Du hast halt dann eventuell das Problem, dass die Uhrzeit auf den verschiedenen Clients nicht synchron ist. Ob das jedoch in Deinem Anwendungsfall etwas ausmacht, mußt Du beurteilen.
          <br><br>
          Wenn Du es in der Client-Anwendung machst, dann am besten natürlich, wenn alles in einer Transaktion läuft, damit ein Änderungsdatum nicht irrtümlich gesetzt wird, obwohl eine der vorangegangen Operationen fehlgeschlagen ist.
          <br><br>
          Thoma
          Thomas Steinmaurer

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

          Comment


          • #6
            @Thomas:
            >ein nettes Beispiel, wo sogenannte Statement-Level Trigger wieder Sinn machen würden. ;-)

            Hmm Du bringst mich auf eine Idee, man kann doch Trigger aktivieren und deaktivieren. Vielleicht ist dieser Weg ja möglich ?

            >Du hast natürlich recht, der Trigger wird für jeden geänderten Datensatz aufgerufen
            Habe mir diese Idee noch etwas durch den Kopf gehen lassen und werde vielleicht doch auf diese Möglichkeit zurückgreifen. Wenn das in einer vernünftigen Zeit durchläuft, ist es im Prinzip ja egal, das er den Trigger bei jedem geänderten Datensatz aufruft. Und vielleicht kann man das ja kombinieren meinem o.a. Vorschlag.

            >Wenn Du es in der Client-Anwendung machst, dann am besten natürlich, wenn alles in einer Transaktion läuft, damit ein Änderungsdatum nicht irrtümlich gesetzt wird, obwohl eine der vorangegangen Operationen fehlgeschlagen ist.

            Die Datensätze werden jeweils einzeln über TIBSQL (Insert-Statement) in Tab1 eingetragen. Als Transaktion wird nach Defaultmäßig "TACommit" übergeben. Es läuft also nicht alles in einer Transaktion, wie ich es zur Zeit verstehe, oder ? Wie müßte ich es umstellen, damit alles in einer Transaktion läuft ?

            Wie Du siehst, bin ich immer noch ein wenig unsicher und tendiere im Moment eher zur Trigger-Lösung.

            Grüsse,
            Carste

            Comment


            • #7
              Hi,
              <br><br>
              ja, man kann einen Trigger deaktivieren/aktivieren, aber dann passiert das datenbankweit, d.h. für alle verbundenen Benutzer, und nicht nur für die "Session" in der das Deaktivieren stattgefunden hat. Du müßtest somit, bevor der letzte Datensatz eingefügt wird, eine eigene Transaktion starten, in der der/die Trigger aktiviert wird. Diese Transaktion dann committen, und in der anderen Transaktion das letzte INSERT-Statement ausführen, das dann vom Trigger mitprotokolliert wird. IMHO nicht wirklich sauber. ;-)
              <br><br>
              Was man in einem Trigger noch machen könnte ist, dass man den vollständigen Trigger-Body noch mit einer IF-Bedingung umschließt, die z.B. auf den aktuell verbundenen Benutzer überprüft, und nur wenn es sich um einen bestimmten Benutzer handelt, dann soll der restliche Code (=Mitprotokollieren des Zeitstempels) ausgeführt werden. Das würde allerdings voraussetzen, dass Deine Sache mit einem eigenen DB-Benutzer stattfindet. Diese Vorgehensweise wird zum Beispiel bei der Replikation verwendet, damit der Replikationprozess selbst nicht wieder durch einen Trigger mitprotokolliert wird.
              <br><br>
              Bzgl. eigener Transaktion. IBX ist bei mir schon etwas her, aber im Prinzip verwendest Du eine eigene TIBTransaction, die von Deinem TIBSQL verwendet wird. Du startest explizit eine Transaktion, d.h. kein AutoCommit-Modus verwenden, machst alle notwendigen Operationen und danach ein Commit, und im Fehlerfall ein Rollback. Mit einem try/except Block kann man das sehr ordentlich machen. Zum Beispiel:
              <pre>
              IBTransaction1.StartTransaction;
              try
              ... Alle Deine notwendigen Operationen
              IBTransaction1.Commit;
              except
              IBTransaction1.Rollback;
              raise; // Optional, falls Du die Exception nochmals werfen (oder auf österreichisch "schmeißen" möchtest ;-)
              end;
              </pre>
              Wichtig bei obigem Beispiel ist halt, dass Deine TIBSQL Komponente auch wirklich diese Transaktionskomponente verwendet. Ich denke Du solltest hier bei TIBSQL eine eigene Property finden, wo man eine TIBTransaction auswählen kann.<br><br>
              Ein kleiner Tipp noch zur Verwendung von TIBSQL in Bulk-Operationen. Wenn möglich, immer das Ganze parametrisiert machen, d.h. ein INSERT INTO Statement mit Parametern. Dieses Statement wird dann <b>einmal</b> Prepared, und bei jedem Durchlauf werden die Parameterwerte gesetzt, und das Statement ausgeführt. Das wird Dir nochmals einen weiteren Performanceschub geben.
              <br><br>
              Thoma
              Thomas Steinmaurer

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

              Comment

              Working...
              X