Announcement

Collapse
No announcement yet.

DBGrid Aktuelle Daten über IBX TIBDataSet

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

  • DBGrid Aktuelle Daten über IBX TIBDataSet

    Hallo,

    habe eine Interbase-Tabelle, deren Daten über ein TIBDataSet in ein DBGrid angezeigt werden.

    Sobald der User einen neuen Datensatz eingibt, wird der Datensatz mit Transaction1.CommitRetaining in der Datenbank gespeichert. Die IBX-Datenbank sorgt dafür, daß dem Datensatz noch ein Datum sowie eine Uhrzeit verpaßt wird.

    In dem Grid kann ich diese Information jedoch nicht sehen, obwohl ich ForcedRefresh auf TRUE gesetzt habe. Auch nicht nach Betätigen des Refresh-Buttons in der Navigator-Leiste sind diese 2 Infos (Uhrzeit und Datum) nicht sichtbar.

    Schließe ich jedoch das Programm und öffne es wieder, so sehe ich die beiden o.a. Infos auch im Grid.

    Wie kann ich dieses Problem beheben ???

  • #2
    hi Carsten, das ist normal!
    <PRE>
    var i : integer;
    begin
    myDatasource.enabled := false;
    with myIBDataSet do begin
    i := fieldbyName('PK_IDNR').value; // Ich hoffe, Du hast einen PK
    active := false;
    active := true;
    locate('PK_IDNR',i,[]) // oder ,..[loCaseInsensitive])
    end;
    myDatasource.enabled := true;
    end;

    </PRE>

    gruß, bernhar

    Comment


    • #3
      Hallo Bernhard,

      wo setze ich Deine Lösung nun am sinnvollsten ein:

      Nach dem Speichern in der Datenbank (AfterPost-Event) oder nach dem Klicken des Refresh-Buttons oder einfach in beiden?

      Grüsse,

      Carste

      Comment


      • #4
        Hallo,

        &gt;wo setze ich Deine Lösung nun am sinnvollsten ein?

        der InterBase ist ein SQL-Server, von dem der Client immer nur eine Kopie der Daten erhält, die zum Zeitpunkt der Client-Transaktion beim Ausführen der SELECT-Abfrage gültig ist. Die IBX-Komponenten puffern die Daten der Kopie lokal im Arbeitsspeicher. Wenn die Datenbank intern (Trigger etc.) bestimmte Spaltenwerte des Datensatzes ändert, bekommt der Client dies nur dann mit, wenn <br>
        a) der Client seine Kopie der Daten über das erneute Ausführen der SELECT-Anweisung neu anfordert und <br>
        b) dies im Kontext einer Transaktion geschieht, deren Transaktionsnummer >= der vorherigen Insert/Update-Transaktion ist

        Wenn der Client in jedem Fall <b>sofort</b> die neuen Daten braucht, kann die Eigenschaft <b>ForcedRefresh</b> für TIBDataSet aktiviert werden (siehe auch Eigenschaft <B>RefreshSQL</b>). Wenn der Client aber die Daten nicht unmittelbar sofort benötigt, würde ich das Ganze so lange verschieben, bis ein COMMIT über die Leitung geht, da in diesem Fall alle aktiven Datenmengen automatisch geschlossen werden und somit neu geöffnet werden müssen

        Comment


        • #5
          Hallo, es lag wohl in meinem Fall an der Refresh-SQL. Ich habe sie jetzt insofern abgeändert, daß die Werte auf jeden Fall bekannt sind, die herausgesucht werden:

          <PRE>
          Select NAME, LANGNAME, VERIFIED_BY, VERIFIED_ON, VERIFIED_AT
          from NAME
          where
          NAME = :NAME
          AND
          LANGNAME = :LANGNAME
          ORDER BY NAME

          Meine bisherige Refresh-SQL sah so aus:
          Select NAME, LANGNAME, VERIFIED_BY, VERIFIED_ON, VERIFIED_AT
          from NAME
          where
          NAME = :NAME
          AND
          LANGNAME = :LANGNAME
          AND
          VERIFIED_BY = :VERIFIED_BY
          AND
          VERIFIED_ON = :VERIFIED_ON
          AND
          VERIFIED_AT = :VERIFIED_AT
          ORDER BY NAME
          </PRE>

          Das neue Problem, das sich nun bei mir stellt, läßt sich wie folgt darstellen:
          Wenn ich das Programm nun starte, und einen neuen Datensatz eingebe, so sehe ich diesen Datensatz (z.B. Name: ACB) im Grid hinter dem Namen "CHJ".

          Das Programm fügt Datensätze anscheinend wahlweise irgendwo im Grid ein oder auch manchmal am Ende des Grids.
          Bisher kann ich diesbezüglich noch kein Schema feststellen. ForcedRefresh ist übrigens auf TRUE.

          Wann setzte ich am besten COMMIT ein? Und wann am besten COMMITRETAINING? Bisher habe ich es in dieser Anwendung nicht explizit irgendwo in Delphi angegeben.

          Grüsse,
          Carste

          Comment


          • #6
            Kurzer Nachtrag:

            Kann es sein, daß das Einfügen des Datensatzes etwas mit der sichtbaren Anzeigemenge des DBGrids zu tun hat?
            Es wäre schön, wenn jemand das Phänomen und einen Lösungsansatz beschreiben könnte

            Comment


            • #7
              Hallo,

              jede SQL-Datenbank arbeitet mengenorientiert, so dass es keine Datensatzposition gibt. Der SQL-Standard sieht folgendes vor: Die Reihenfolge der Datensätze in der Ergebnismenge wird erst dann bestimmt, wenn eine SELECT-Abfrage mit einer ORDER BY-Anweisung ausgeführt wird. IBX verwendet jedoch für das Einfügen einen lokalen Datensatzpuffer, so dass es "legal" ist, diesen neuen Datensatz im sichtbaren Bereich des TDBGrid irgendwo einzuordnen und anzuzeigen. Erst dann, wenn die SELECT-Abfrage mit der ORDER BY-Anweisung neu ausgeführt wird, muss die Position stimmen.

              &gt;Wann setzte ich am besten COMMIT ein?

              So oft es geht, hinter COMMITRETAINING steckt nur ein Kompromiss. Wenn nach dem Einfügen eines neuen Datensatzes ein COMMIT ausgelöst wird, schließt IBX automatisch alle offenen Datenmengen. Soll der Anwender das Ergebnis aber sehen, muss die SELECT-Abfrage (mit ORDER BY) neu ausgeführt werden, so dass der Datensatz in jedem Fall an der richtigen Position eingeordnet wird. Bestätigt man den neu eingefügten Datensatz jedoch über COMMITRETAINING, so bleibt die alte Ergebnismenge bestehen (ist zwar für uns am Anfang bequemer, hat aber Nachteile für den InterBase, die sich im Laufe der Zeit summieren)

              Comment

              Working...
              X