AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Thema durchsuchen
Ansicht
Themen-Optionen

TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

Offene Frage von "Uwe Raabe"
Ein Thema von Bodenseematze · begonnen am 26. Aug 2024 · letzter Beitrag vom 29. Aug 2024
Antwort Antwort
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.631 Beiträge
 
Delphi 12 Athens
 
#1

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 26. Aug 2024, 13:18
UpdatesPending ist True, wenn Records (nicht zwingend der aktuelle Record!) verändert, hinzugefügt oder gelöscht wurden, und es kommt nur bei aktivem CachedUpdates vor. Deswegen geht es nach einem ApplyUpdates bzw. CommitUpdates wieder weg.

Der Status des aktuellen Records wird in Modified geführt. Es kann aber sein, dass noch nicht alle Änderungen in den datensensitiven Controls berücksichtig wurden. In dem Fall genügt ein Aufruf von UpdateRecord um das zu aktualisieren. Das ist übrigens bei allen DataSets so und hat nichts mit der BDE zu tun.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Bodenseematze

Registriert seit: 10. Jul 2023
69 Beiträge
 
#2

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 26. Aug 2024, 14:56
UpdatesPending ist True, wenn Records (nicht zwingend der aktuelle Record!) verändert, hinzugefügt oder gelöscht wurden, und es kommt nur bei aktivem CachedUpdates vor. Deswegen geht es nach einem ApplyUpdates bzw. CommitUpdates wieder weg.
Das heißt im Umkehrschluss, dass ohne CachedUpdates nur der aktuelle Datensatz geändert sein kann?

Und: warum ist bei mir (bei nur einem Record!) dann UpdatesPending auf True gesetzt?

Der Status des aktuellen Records wird in Modified geführt. Es kann aber sein, dass noch nicht alle Änderungen in den datensensitiven Controls berücksichtig wurden. In dem Fall genügt ein Aufruf von UpdateRecord um das zu aktualisieren. Das ist übrigens bei allen DataSets so und hat nichts mit der BDE zu tun.
Also sicherheitshalber immer vor der Status/Modified-Abfrage ein UpdateRecord()-Aufruf einfügen? Oder kann ich irgendwie abfragen, ob das notwendig ist?

Das kann ja dann nur für den aktuellen Record gelten, oder?
Wie ist das bei Master/Detail, wenn die Detail-Datensätze in eine TDBGrid enthalten sind?
Könnte es da mehrere Datensätze geben, bei denen noch ein UpdateRecord gemacht werden muss?

Geändert von Bodenseematze (26. Aug 2024 um 15:13 Uhr) Grund: zu spät - kommt in eigene Antwort...
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.631 Beiträge
 
Delphi 12 Athens
 
#3

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 26. Aug 2024, 15:08
Das heißt im Umkehrschluss, dass ohne CachedUpdates nur der aktuelle Datensatz geändert sein kann?
Das weiß ich tatsächlich nicht, da ich die BDE-Sourcen gerade nicht verfügbar habe (ich glaube sogar, die waren nie verfügbar). Ich vermute, dass das aber nicht für den aktuellen Datensatz gilt, da dieser ja bei Cancel nicht in den Update-Buffer übernommen wird.

Und: warum ist bei mir (bei nur einem Record!) dann UpdatesPending auf True gesetzt?
Das kann ich dir aus demselben Grund auch nicht sagen.

Also sicherheitshalber immer vor der Status/Modified-Abfrage ein UpdateRecord()-Aufruf einfügen?
Ja, wenn der State in [dsEdit, dsInsert] ist.

Oder kann ich irgendwie abfragen, ob das notwendig ist?
Nein.

Das kann ja dann nur für den aktuellen Record gelten, oder?
Wie ist das bei Master/Detail, wenn die Detail-Datensätze in eine TDBGrid enthalten sind?
Könnte es da mehrere Datensätze geben, bei denen noch ein UpdateRecord gemacht werden muss?
Jedes DataSet hat seinen eigenen Modified Status, egal ob Master/Detail oder nicht. Es betrifft immer den jeweils aktuellen Datensatz. Wenn du also ein Master- und ein Detail-DataSet hast, dann musst du das bei beiden machen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Bodenseematze

Registriert seit: 10. Jul 2023
69 Beiträge
 
#4

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 26. Aug 2024, 15:25
Das heißt im Umkehrschluss, dass ohne CachedUpdates nur der aktuelle Datensatz geändert sein kann?
Das weiß ich tatsächlich nicht, da ich die BDE-Sourcen gerade nicht verfügbar habe (ich glaube sogar, die waren nie verfügbar). Ich vermute, dass das aber nicht für den aktuellen Datensatz gilt, da dieser ja bei Cancel nicht in den Update-Buffer übernommen wird.
Also bei "normalen" TDataSets (ohne CachedUpdates) bzw. wenn CachedUpdates auf False steht, muss ich über alle Records loopen und deren Modified abgfragen, damit ich herausfinde ob einer der Records geändert ist?
Oder wird dort dann automatisch beim Wechsel des Records die geänderten Daten in die Datenquelle geschrieben?
Dann wäre es in dem Fall ja tatsächlich nur möglich, dass der aktuelle Record Änderungen hat...

Und: warum ist bei mir (bei nur einem Record!) dann UpdatesPending auf True gesetzt?
Das kann ich dir aus demselben Grund auch nicht sagen.
Das finde ich immer noch sehr seltsam und unlogisch!

[EDIT]: ich habe in meinen Quellen mal nachgeschaut, das Property UpdatesPending ist über einen Getter in TBDEDataSet folgendermaßen implementiert:
Delphi-Quellcode:
function TBDEDataSet.GetUpdatesPending: Boolean;
begin
  Result := GetIntProp(FHandle, curDELAYUPDNUMUPDATES) > 0;
end;
Damit bin ich so schlau wie vorher - zumal ich curDELAYUPDNUMUPDATES nirgends definiert finden kann

Und der Aufruf von UpdateStatus() macht auch nur Sinn, wenn CachedUpdates gesetzt ist - nur dann bringt es einen Wert ungleich usUnmodified zurück. Und es bezieht sich wohl auch nur auf den aktuellen Record (zumindest lt. Doku)...

Also sicherheitshalber immer vor der Status/Modified-Abfrage ein UpdateRecord()-Aufruf einfügen?
Ja, wenn der State in [dsEdit, dsInsert] ist.
Das habe ich auch gerade gemerkt - einfach "immer" aufgerufen, fliegt ggf. eine Exception, dass sich "die Datenmenger weder im Editier- noch im Einfügemodus befindet"...
--> dann macht das ja nur Sinn, wenn ich bereits weiß, dass ich im Editier-/Insert-Modus bin und ich Fields auf Änderungen prüfen möchte, oder?
[EDIT]: lt. Embarcadero-Doku ist der Aufruf für die Gegenrichtung zuständig, d.h. es werden die Controls davon informiert, dass sich im Record Änderungen befinden - wenn das so ist, benötige ich es sicherlich für diesen Anwendungsfall hier nicht...

Jedes DataSet hat seinen eigenen Modified Status, egal ob Master/Detail oder nicht. Es betrifft immer den jeweils aktuellen Datensatz. Wenn du also ein Master- und ein Detail-DataSet hast, dann musst du das bei beiden machen.
Ja, das ist schon klar - ich meinte, wenn z.B. im Detail-Grid mehrere Zeilen geändert sind - dann muss ich eine Schleife über alle Records des Detail-DataSet machen und kann nur so herausfinden, ob Records: neu sind oder geändert sind oder gelöscht wurden, oder verstehe ich das immer noch falsch?

Geändert von Bodenseematze (26. Aug 2024 um 16:33 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.631 Beiträge
 
Delphi 12 Athens
 
#5

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 26. Aug 2024, 17:54
muss ich über alle Records loopen und deren Modified abgfragen, damit ich herausfinde ob einer der Records geändert ist?
Nein, denn lediglich der aktuelle Record kann Modified sein. Alle anderen sind ja nach einer etwaigen Änderung entweder durch Cancel in den ursprünglichen Zustand zurück versetzt oder durch Post gespeichert worden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Bodenseematze

Registriert seit: 10. Jul 2023
69 Beiträge
 
#6

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 27. Aug 2024, 07:52
muss ich über alle Records loopen und deren Modified abgfragen, damit ich herausfinde ob einer der Records geändert ist?
Nein, denn lediglich der aktuelle Record kann Modified sein. Alle anderen sind ja nach einer etwaigen Änderung entweder durch Cancel in den ursprünglichen Zustand zurück versetzt oder durch Post gespeichert worden.
Das widerspricht jetzt völlig meinem Verständnis.

Wohin wird das denn durch "Post" gespeichert?
Bei der ersten Änderung des Master- oder eines der Detail-Datensätze starte ich auf der Datenbank eine Transaktion - dann können soviel Änderungen durchgeführt werden wie gewünscht.
Und erst wenn alle Änderungen entweder gespeichert (Commit) oder verworfen (Rollback) werden, sind die Änderungen weg.
Und bis dahin muss ich doch programmtechnisch feststellen können, ob sich im Master-Datensatz oder einem der Detail-Datensätze Änderungen (d.h. es sind Daten im Query ggü. dem Datenbankinhalt verändert) befinden.

Und da möchte ich eben verstehen, mit welchen Properties / Aufrufen etc. auf den TQuery / TDataSet (oder auch sonst irgendwie) ich das einfachst möglich - aber korrekt - feststellen kann...
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.371 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 27. Aug 2024, 09:24
CachedUpdates sorgt dafür, dass Änderungen nicht sofort an die Datenbank geschickt werden. Deswegen kann man über UpdatesPending prüfen, ob noch was im Cache ist. D.h. man hat zwar lokal (in der Anwendung) Änderungen, aber die stehen noch nicht in der DB. Dafür sorgt dann ApplyUpdates. Bei einem Programmabsturz sind deine lokalen Änderungen dann nicht in der DB. Der Vorteil von CachedUpdates ist der geringere Netzwerkverkehr. Liegt die DB lokal auf dem Anwendungsrechner, bringt CachedUpdates nicht mehr viel.
Schaltet man CacheUpdates aus, müsste UpdatesPending immer False liefern.

Zum Problem:
Du verwendest Queries, wenn ich es richtig gesehen habe. Diese können eigene DML-Anweisungen (Edit, Delete, Insert) haben, die unter Umständen automatisch ausgelöst werden. Selbst wenn keine echten Änderungen vorliegen kann es solche Situationen geben, die manchmal kaum nachvollziehbar sind. Damit meine ich Änderungen, die zwar von der Komponente registriert werden, aber die Inhalte trotzdem unverändert sind. Ein Update ohne inhaltliche Änderungen ist immer noch ein Update. Unter Umständen kann es dann sogar passieren, dass ein ApplyUpdates zu einem Fehler führt.

Die Ursachen können vielfältig und teilweise kaum zu erklären sein. Ich denke aber, dass es nichts mit der BDE zu tun haben wird. Irgendein Event kann bei einem Vergleich zu einem ungewollten Update führen. Eine Formatierung für ein Edit-Feld führt scheinbar zu einer Änderung. Komplexe Master-Detail-Abhängigkeiten können bei manueller Steuerung auch dazu führen. Eine ungewolltes oder unkontrolliertes Edit/Post kann ein LiveUpdate auslösen und dadurch ein UpdatesPending auf True setzen. Ich meine auch mal gelesen zu haben, dass bestimmte Prefixe bei Feldnamen zu so einem Problem geführt haben sollen.

Da du sowieso mit Transaktionen arbeitest, würde ich CachedUpdates deaktivieren. Wenn du nicht gerade Massenänderungen machst, ist der Netzwerkverkehr zu vernachlässigen und in dem Fall könntest du CachedUpdates auch gezielt aktivieren.
Peter
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.631 Beiträge
 
Delphi 12 Athens
 
#8

AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"

  Alt 27. Aug 2024, 10:27
Das widerspricht jetzt völlig meinem Verständnis.
Dann empfehle ich die Studie der einschlägigen Lektüre. Obwohl nicht mehr ganz so einfach zu finden, steht in der Hilfe doch so einiges zum Thema Cached Updates drin: https://docwiki.embarcadero.com/Libr....CachedUpdates

Wohin wird das denn durch "Post" gespeichert?
Wie in der Doku erwähnt, in einen lokalen Speicherbereich, der im Format einer Paradox-Table entspricht.

Bei der ersten Änderung des Master- oder eines der Detail-Datensätze starte ich auf der Datenbank eine Transaktion - dann können soviel Änderungen durchgeführt werden wie gewünscht.
Und erst wenn alle Änderungen entweder gespeichert (Commit) oder verworfen (Rollback) werden, sind die Änderungen weg.
Bei CachedUpdates ist die Transaktions-Steuerung gar nicht involviert. Das findet ausschließlich im DataSet (TQuery) statt. Erst beim Aufruf von ApplyUpdates wird die Datenbank involviert und die Transaktion bekommt die Daten. Wenn du bereits vorher eine Transaktion gestartet hast, dann hat das lediglich Einfluss darauf, welche Änderungen von anderen Clients du sehen kannst. Deine eigenen Änderungen sind vor dem ApplyUpdates gar nicht in der Datenbank vorhanden.


Und bis dahin muss ich doch programmtechnisch feststellen können, ob sich im Master-Datensatz oder einem der Detail-Datensätze Änderungen (d.h. es sind Daten im Query ggü. dem Datenbankinhalt verändert) befinden.

Und da möchte ich eben verstehen, mit welchen Properties / Aufrufen etc. auf den TQuery / TDataSet (oder auch sonst irgendwie) ich das einfachst möglich - aber korrekt - feststellen kann...
Wenn der aktuelle Datensatz im Insert/Edit Mode ist, dann gibt Modified an ob dieser geändert wurde (gegebenenfalls erst nach Aufruf von UpdateRecord). Ergänzend dazu gibt UpdatesPending an, ob es bereits andere Änderungen an den Daten der Query seit dem letzten ApplyUpdates gegeben hat, die aber noch nicht an die Datenbank übertragen wurden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:47 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz