![]() |
TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Hallo zusammen,
ich weiß: BDE ist alter Tobak und sollte ersetzt werden, genau wie das von mir verwendete Delphi 7... ...aber ich muss es halt aktuell (noch) verwenden :oops: (und außerdem bin ich nicht sicher, ob es nicht bei anderen TDataSet-Klassen auch so ist) Vielleicht kann mir trotzdem noch jemand aus seiner Erfahrung berichten - ich verstehe nämlich nicht so ganz, wie ich erkenne, ob sich ein Datensatz geändert hat oder nicht... Hier kurz meine Problemschilderung: Ich versuche in meinen datenbankbasierten Masken anzuzeigen, ob sich der aktuell aufgeschaltete Datensatz geändert hat (d.h. ob eine der Datenbankfelder auf der Maske sich verändert haben oder ob der gesamte Datensatz neu ist). Die Datenbankverbindung ist zu einem MS-SQL Server über einen ODBC-Eintrag gemacht - es wird in der BDE entsprechend die ODBC-DSN verwendet. Auf der Maske ist ein TQuery mit CachedUpdates=True, UpdateMode=upWhereKeyOnly und UpdateObject gesetzt (Rest der Properties sind "false") und das dazugehörige TDataSource, dass sich auf die Query als DataSet bezieht; alle auf der Maske befindlichen Edit-Felder beziehen sich auf diese TDataSource und ein DataField aus dem TQuery. Um zu prüfen, ob Änderungen im Query sind, wird in einer allgemeinen Methode "HasChanges" folgendes geprüft:
Delphi-Quellcode:
Wenn ich jetzt direkt nach dem Öffnen des Queries mit einem (!) Datensatz die Prüfmethode aufrufe, kommt "true" (d.h. es gibt Änderungen) zurück.
Result := false;
if ( qry.Active and qry_.CanModify ) then begin if ( (qry_.State = dsEdit) or (qry_.State = dsInsert) ) then begin Result := true; end else if ( qry_.CachedUpdates and qry_.UpdatesPending ) then begin Result := true; end; end; Wenn ich mir das Query genauer anschaue, sehe ich folgendes: Active=true, CanModify=true, RecordCount=1, UpdateStatus()=Modified, State=dsBrowse, CachedUpdates=true, UpdatesPending=true Und wenn ich über alle Fields in dem Datensatz laufe und mir diese anschaue, sehe ich keinerlei Änderungen (Value, NewValue, ggf. OldValue sind alle gleich). Wieso wird mir als "UpdateStatus()" Modified zurückgeliefert? :shock: Und warum ist "UpdatesPending" gesetzt? :gruebel: Und das direkt in "AfterScroll"!? Ich glaube, ich verstehe die Properties sowie die Methode "UpdateStatus()" nicht so richtig... :oops: ...kann mir da jemand Licht ins Dunkel :idea: bringen? |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Status steht auf Browse, nicht auf dsEdit oder dsInsert ... OldValue und NewValue können somit garnicht unterschiedlich sein.
Nja, es liegt ja eh am UpdatesPending=True. Du hast also "wartende" Änderungen? Und somit stimmt des True. :angle2: Frag mich aber nicht, wie man ins ÄnderungsLog, bzw. in die Änderungsliste (wartende Update) reinschaut. Keine Ahnung. qry_.UpdatesPending kann eigentlich nur True sein, wenn qry_.CachedUpdates es auch ist, womit man die eine Prüfung weglassen können dürfte.
Delphi-Quellcode:
if qry_.State in [dsEdit, dsInsert] then begin
Delphi-Quellcode:
Result := ( qry.Active and qry_.CanModify )
and ( (qry_.State in [dsEdit, dsInsert]) or qry_.UpdatesPending ); |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Ich bin mir nicht bewußt, dass sowas vorliegt.. Zitat:
Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
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. |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Und: warum ist bei mir (bei nur einem Record!) dann UpdatesPending auf True gesetzt? Zitat:
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? |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
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... Zitat:
[EDIT]: ich habe in meinen Quellen mal nachgeschaut, das Property UpdatesPending ist über einen Getter in TBDEDataSet folgendermaßen implementiert:
Delphi-Quellcode:
Damit bin ich so schlau wie vorher - zumal ich curDELAYUPDNUMUPDATES nirgends definiert finden kann :?
function TBDEDataSet.GetUpdatesPending: Boolean;
begin Result := GetIntProp(FHandle, curDELAYUPDNUMUPDATES) > 0; end; 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)... Zitat:
--> 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... Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
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... :wink: |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:53 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 by Thomas Breitkreuz