Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi neuere Datzensätze fehlen beim Abfragen (https://www.delphipraxis.net/192727-neuere-datzensaetze-fehlen-beim-abfragen.html)

Helmi 14. Mai 2017 19:54

Datenbank: Firebird • Version: 2.5 • Zugriff über: ZEOS

neuere Datzensätze fehlen beim Abfragen
 
Hallo,

mit folgendem Code frag ich Datensätze ab:
Delphi-Quellcode:
  //Filter setzen
  with DataModule_DB.ZQuery do
    begin
      Close;

      SQL.Clear;
      SQL.Add('SELECT DATUM, UHRZEIT, TEMPSENSOR_1, FEUCHTESENSOR_1 FROM Wetterdaten ');

      If not alle_Datensaetze then
        SQL.Add('WHERE DATUM = :DATE');

      SQL.Add('ORDER BY UHRZEIT');

      //Parameter
      If not alle_Datensaetze then
        ParamByName('DATE').AsDate := Datum;

      Open;
    end;
Dies funktioniert genau 1x.
Alle paar Minuten kommt ein neuer Datensatz in die Datenbank.
Frag ich danach mit dem o. g. Code wieder ab, so fehlt der neue Datensatz.

Erkennen tu ich es in einem DBGrid, dass der Eintrag fehlt.

Das DBGrid wird vom ZQuery versorgt.

Was mach ich falsch, bzw. wie bekomm ich die anderen, neueren Datensätze?

nahpets 14. Mai 2017 20:10

AW: neuere Datzensätze fehlen beim Abfragen
 
Hast Du irgendwo Transaktionen?
Schreibst Du die neuen Datensätze mit Commit fest?
Welchen Wert hat die Eigenschaft TransactIsolationLevel der TZConnection?

Sind schreibendes und lesendes Programm das gleiche?
Oder schreibt ein Programm in die Datenbank und ein anderes holt die Daten ab?

Helmi 14. Mai 2017 20:25

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von nahpets (Beitrag 1371394)
Hast Du irgendwo Transaktionen?

Nein - jedenfalls sind mir keine bekannt (mit meinem Minimalwissen an Datenbank)

Zitat:

Zitat von nahpets (Beitrag 1371394)
Schreibst Du die neuen Datensätze mit Commit fest?

leider hast du mich jetzt erwischt - wie kann ich das feststellen oder nicht?

Zitat:

Zitat von nahpets (Beitrag 1371394)
Welchen Wert hat die Eigenschaft TransactIsolationLevel der TZConnection?

Auf dem Server "tiRepeatableRead".
Beim Client war das bisher auch, jetzt hab ich es auf "tiReadCommitted" geändert und jetzt bekomm ich auch die Datensätze angezeigt

Zitat:

Zitat von nahpets (Beitrag 1371394)
Sind schreibendes und lesendes Programm das gleiche?
Oder schreibt ein Programm in die Datenbank und ein anderes holt die Daten ab?

Ein Programm auf dem Server schreibt in die Datenbank, ein zweites Programm (Client) liest nur aus

bnreimer42 14. Mai 2017 20:40

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo,

schau Dir die Sache mit den Transaktionen an und schalte alle Automatik der Client-Komponenten aus.

Ist eigentlich ganz einfach, ähnlich wie der Umgang mit einer Datei.

Am Anfang Begin Transaction (ähnlich Datei öffnen)
Alle Statements ändern innerhalb der laufenden Transaktion Daten. Andere Transaktionen sehen die Änderungen erst mal nicht. (ähnlich schreiben in gesperrte Datei)
Wenn Du fertig bist: Commit (ähnlich Datei schließen)
Wenn etwas schief gelaufen ist: Rollback, d.h. alles, was seit Begin Transaction geschehen ist, wird ungeschehen gemacht (Außer Spezialitäten, wie z.B. Erhöhen einer Sequenz)

Beim Lesen beginnst Du auch mit Begin Transaction
Bis zum Commit (oder Rollback) bleibt bei Repeatable Read der Datenbestand gleich
Wenn Du neue Daten erwartest, vor dem Lesen der Daten Commit einschieben.

Alternativ setzt Du die Lesetransaktion auf ReadCommited, dann siehst Du da immer alle Änderungen, die irgendjemand Commited hat.


Die meisten Komponenten machen das Begin Transaction alleine, d.h. wenn keine Transaction offen ist, öffnen sie eine.


Das Funktioniert - ich denke bei ZEOS auch - indem Du zusätzlich explizit ein Transaktionsobjekt anlegst und mit der Query oder Table verbindest.
Das Objekt hat auch die Methoden BeginTransaction, Commit und Rollback. (oder so ähnlich)

Jasocul 15. Mai 2017 06:09

AW: neuere Datzensätze fehlen beim Abfragen
 
Transaktionen im schreibenden Programm können natürlich die Ursache sein, aber ich habe hier das Feld "Datum" im Verdacht.
Hast du schon direkt in der Datenbank nachgesehen, was in dem Feld steht?
Wenn das Feld auch die Uhrzeit enthält, schlägt der Vergleich in der SQL-Abfrage fehl.

Hast du auch schon geprüft, ab die Abfrage ohne Datums-Vergleich funktioniert?
Stehen die "fehlenden" Datensätze denn tatsächlich in der Datenbank drin?

hoika 15. Mai 2017 08:05

AW: neuere Datzensätze fehlen beim Abfragen
 
Haqllo,
ob es an den Transaktionen liegt, ist einfach zu prüfen.
Dazu reicht es aus, das Anzeigeprogramm neu zu starten.
Sind die Werte iim Grid, liegt es an der fehlenden Transaktionssteuerung,
d.h. das Anzeigeprogramm startet zu Programmbeginn eine Transaktion und
zeigt dann auch nur die Datensätze an, die vor den Transaktionsstart comitted waren.

wie schon gesagt wurde.
Zitat:

Das Funktioniert - ich denke bei ZEOS auch - indem Du zusätzlich explizit ein Transaktionsobjekt anlegst und mit der Query oder Table verbindest.
Das Objekt hat auch die Methoden BeginTransaction, Commit und Rollback. (oder so ähnlich)
Also vor der Aktualisierung des Grids einfach eine Query.Connection.BeginTransaction
danach Query.Connection.Commit.
Query.Connection könnte auch Query.DataBase bei ZEOS heißen.

Helmi 15. Mai 2017 08:16

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von Jasocul (Beitrag 1371402)
Transaktionen im schreibenden Programm können natürlich die Ursache sein, aber ich habe hier das Feld "Datum" im Verdacht.
Hast du schon direkt in der Datenbank nachgesehen, was in dem Feld steht?
Wenn das Feld auch die Uhrzeit enthält, schlägt der Vergleich in der SQL-Abfrage fehl.

Hast du auch schon geprüft, ab die Abfrage ohne Datums-Vergleich funktioniert?
Stehen die "fehlenden" Datensätze denn tatsächlich in der Datenbank drin?

Im Feld Datum steht nur das Datum.
In der Datenbank hat nie ein Datensatz gefehlt. So hab ich es ja festgestellt, dass ich im Client nicht immer alle Datensätze erhalten habe.

Seitdem ich den Client auf tiReadCommitted gestellt habe, funktioniert es.

jobo 15. Mai 2017 08:24

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von hoika (Beitrag 1371419)
..

Also vor der Aktualisierung des Grids einfach eine Query.Connection.BeginTransaction
danach Query.Connection.Commit.
Query.Connection könnte auch Query.DataBase bei ZEOS heißen.

Also das scheint mir nicht richtig zu sein.
Transaktionshandling in einem Anzeigeprogramm ändert gar nichts.
Transaktionen sollten -falls sie nicht auf Automatic stehen- von dem Code gesteuert werden, der DML macht.

Die Sichtbarkeit der Daten ist dann so:
Der Client, der in-transaction ist sieht alles was andere commited haben plus seine eigenen "offenen" Transactionsdaten.
Andere Clients sehen davon nichts, egal wieviel Begin-/Endtransactions sie machen.

Spannender wird es natürlich, wenn Anzeige und Änderung in einem Programm erfolgen. Gemäß oben, sollte ein Client, der einfügt/ändert auch "sehen" können, was er da verzapft. Ist auch normalerweise so (bei "automatic"), außer man verwaltet die Transaktionen selbst. Wenn man das verbockt, und Transaktionen offen lässt (natürlich unbeabsichtigt), wird niemand diese Daten sehen. Ausnahme hier ist natürlich, wenn man nun noch zur Krönung des Chaos beginnt, mit den Isolation Leveln zu experimentieren um "seine Transaktionsdaten" irgendwo zu finden.

Mein Tipp für den Anfang:
Transaktion auf Automatisch. Wenn alles flutscht im Testbetrieb, Testbetrieb erweitern auf 2 oder mehr Clients, ggF. mit konkurrierenden Zugriffen, jenachdem was man überhaupt implementieren will.
Wenn das auch alles flutscht, kann man - wenn man es unbedingt ausprobieren will- manuelles Transaktionshandling einbauen. Und wenn man dann noch immer Spaß hat, kann man auch mit isolation levels spielen, wofür auch immer.
Aus gegebenem Anlaß dazu ein kleiner Vergleich:
Isolation Level != commited sind so ähnlich wie Wahlprognosen. Mglw. total spannend, aber am Ende des Tages bedeutungslos.

Olli73 15. Mai 2017 11:37

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von jobo (Beitrag 1371426)
Transaktionshandling in einem Anzeigeprogramm ändert gar nichts.

Da er TransactIsolationLevel auf tiRepeatableRead stehen hatte, lag es eben doch an einer Transaction.

Auch wenn hier ReadComitted natürlich besser ist.

mjustin 15. Mai 2017 11:47

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von jobo (Beitrag 1371426)
Isolation Level != commited sind (...) bedeutungslos.

Repeatable Read Transaktionen, um einen unveränderlichen Schnappschuss zu erhalten, in dem man die Datenbank völlig unabhängig von Insert/Update/Deletes anderer sehen kann, sind bedeutungslos?

p80286 15. Mai 2017 11:54

AW: neuere Datzensätze fehlen beim Abfragen
 
Zitat:

Zitat von mjustin (Beitrag 1371461)
Zitat:

Zitat von jobo (Beitrag 1371426)
Isolation Level != commited sind (...) bedeutungslos.

Repeatable Read Transaktionen, um einen unveränderlichen Schnappschuss zu erhalten, in dem man die Datenbank völlig unabhängig von Insert/Update/Deletes anderer sehen kann, sind bedeutungslos?

Jetzt hole ich die Chips, es geht los!
K-H

hoika 15. Mai 2017 13:01

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo,
Zitat:

bedeutungslos
Nein, aber nicht wirklich sinnvoll.

Ein jederzeit konsistenter Zustand der Sicht auf die Daten ist aber nur beim ReadCommitted gegeben.

Mein Lieblings-Bsp. ist einer Lagerverwaltung:
Ich mache 14:00 eine Stunde Inventur, habe eine Inventursumme, gehe die einzelnen Positionen durch usw..
14:30 trägt jemand etwas ins Lager ein.

Ich erwarte, dass ich 14:31 immer noch meinen Lagerstand von 14:00 habe.
Sonst stimmt ja meine Summe nicht und ich kann von vorn anfangen.

(Deswegen machen ja viele Papier-Inventur ausserhalb der Arbeitszeit)

jobo 15. Mai 2017 13:55

AW: neuere Datzensätze fehlen beim Abfragen
 
@Chips, bedeutungslos usw.
Ich schrieb ja "am Ende des Tages bedeutungslos". Für wen der Tag wann endet, mag jeder selber entscheiden.
Mir schien es sinnvoll, oder besser ich halte es immer noch für sinnvoll, die möglichen Optionen, die man im Transaktionshandling hat, nach bester Wahl priorisiert darzustellen.

haentschman 15. Mai 2017 14:42

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo Helmi...:P
Ich gebe noch nicht auf, daß du siehst das WITH schlecht ist. :wink:

Vergleich:
Delphi-Quellcode:
//Filter setzen
  with DataModule_DB.ZQuery do
    begin
      Close;
      SQL.Clear;
      SQL.Add('SELECT DATUM, UHRZEIT, TEMPSENSOR_1, FEUCHTESENSOR_1 FROM Wetterdaten ');
      If not alle_Datensaetze then
        SQL.Add('WHERE DATUM = :DATE');
      SQL.Add('ORDER BY UHRZEIT');
      //Parameter
      If not alle_Datensaetze then
        ParamByName('DATE').AsDate := Datum;
      Open;
    end;
gegen...
Delphi-Quellcode:
//Filter setzen
 DataModule_DB.ZQuery.SQL.Text := 'SELECT DATUM, UHRZEIT, TEMPSENSOR_1, FEUCHTESENSOR_1 FROM Wetterdaten ';
 if not alle_Datensaetze then
 begin
   SQL.Add('WHERE DATUM = :DATE');
   DataModule_DB.ZQuery.ParamByName('DATE').AsDate := Datum;
 end;
 DataModule_DB.ZQuery.SQL.Add('ORDER BY UHRZEIT');
 DataModule_DB.ZQuery.Open;
..merkst du was? Du machst es dir schwerer als notwendig ist. :zwinker: Mit dem WITH kannst außerdem du nicht mehr debuggen! ParamByName('DATE').AsDate bringt kein Ergebnis am Breakpoint. Und außerdem brauchst du mehr Quelltextzeilen. :roll:

Wenn du dir nicht helfen lassen willst bin ich hier raus. Ansonsten frage nach... :wink:

mkinzler 15. Mai 2017 15:48

AW: neuere Datzensätze fehlen beim Abfragen
 
Oder noch besser:

Delphi-Quellcode:
 DataModule_DB.ZQuery.SQL.Text := 'SELECT DATUM, UHRZEIT, TEMPSENSOR_1, FEUCHTESENSOR_1 FROM Wetterdaten WHERE (:Alle = 1 or DATUM = :DATE) ORDER BY UHRZEIT';
...
if alle_Datensaetze then
 begin
    DataModule_DB.ZQuery.ParamByName('alle').Value := 1;
 end
 DataModule_DB.ZQuery.ParamByName('DATE').AsDate := Datum;
 DataModule_DB.ZQuery.Open;

hoika 15. Mai 2017 16:19

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo,

Delphi-Quellcode:
var
  Q: TZQuery;
begin
  Q := DataModule_DB.ZQuery;
  Q.

haentschman 15. Mai 2017 17:13

AW: neuere Datzensätze fehlen beim Abfragen
 
...nicht überfordern. :zwinker: Was für uns selbstverständlich ist, ist für andere ein Dorf im Böhmen. :P

Helmi 15. Mai 2017 17:42

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo,

es mag sein, dass manchen, wie ich es auch schon in einem anderen Thread deutlich gemacht habe, mein Programmierstil, bzw. dieser Stil, den ich in dem kleinen Code-Auszug dargestellt habe, nicht gefallen mag.

Unabhängig davon, sehe ich keinen Grund dafür penetrant seinen eigenen, seiner Ansicht nach, schöneren/besseren/kürzeren Stil mit allen Mitteln jemanden aufzuzwingen.

Mir sind die Gefahren "with" zu nutzen mehr als bekannt, was aber nicht die Verwendung verbietet.

Zitat:

Zitat von haentschman (Beitrag 1371506)
...nicht überfordern. :zwinker: Was für uns selbstverständlich ist, ist für andere ein Dorf im Böhmen. :P

Auch wenn ich dir mal unterstelle, dass du dies nicht so herablassend gemeint hast, wie es rüberkommt, sehe ich keinen Grund, dies kundzutun.

Es ist schon der 2. Thread der ins Offtopic abdriftet - nur weil es Mitglieder gibt, die es anscheinend nicht verstehen können, wenn man ihren Programmstil nicht bevorzugt.
Lasst es doch bitte einfach bleiben - es geht um das Problem im ersten Thread - nicht um Schönheitspokale bei der Codegestaltung!

Daniel 15. Mai 2017 17:51

AW: neuere Datzensätze fehlen beim Abfragen
 
Das hier beschriebene Ausgangsproblem liegt ja auch nicht im Zusammenhang mit der Verwendung von "with".
"With" gestaltet den Code üblicherweise unübersichtlicher, dem stimme ich zu. das alles aber in einem Thema für Datenbanken abhandeln zu wollen, ist völlig fehl am Platze. Auch später, wenn Dritte nach einer Lösung zum DB-Problem suchen, sollten sie sich nicht durch Abhandlungen zum Thema "with" durchbeißen müssen. Die Kritik an "with" hat ihre Berechtigung, aber nicht an diesem Platz.

mkinzler 15. Mai 2017 17:52

AW: neuere Datzensätze fehlen beim Abfragen
 
Es geht hier nicht nur um Schönheit, sondern um Performance und Effizienz. Zudem um weniger Fehleranfälligkeit.

haentschman 15. Mai 2017 20:24

AW: neuere Datzensätze fehlen beim Abfragen
 
Hallo Helmi...
Da du mich persönlich angegriffen hast, kann ich das nicht so stehen lassen. :roll:
Zitat:

es mag sein, dass manchen, wie ich es auch schon in einem anderen Thread deutlich gemacht habe, mein Programmierstil, bzw. dieser Stil, den ich in dem kleinen Code-Auszug dargestellt habe, nicht gefallen mag.
Wie schon mkinzler erwähnte, geht es nicht um Schönheit sondern um die Fehleranfälligkeit des Codes. Und bei Fehleranfälligkeit liegt WITH ganz weit oben.
Zitat:

Unabhängig davon, sehe ich keinen Grund dafür penetrant seinen eigenen, seiner Ansicht nach, schöneren/besseren/kürzeren Stil mit allen Mitteln jemanden aufzuzwingen.
Warum sollte ich dir den Stil aufzwingen. Es ist im Vergleich deutlich kürzer und vor Allem debuggbar. Wenn du die Vorteile nicht benutzen möchtest...bitteschön.
Zitat:

Auch wenn ich dir mal unterstelle, dass du dies nicht so herablassend gemeint hast, wie es rüberkommt, sehe ich keinen Grund, dies kundzutun.
...das war definitiv nicht herablassend gemeint. Bei anderen Threads wären zig Varianten aufgezählt worden, daß der TE nicht mehr wußte was eigentlich richtig ist. Ich wollte die Jungs nur bremsen.
Zitat:

Es ist schon der 2. Thread der ins Offtopic abdriftet - nur weil es Mitglieder gibt, die es anscheinend nicht verstehen können, wenn man ihren Programmstil nicht bevorzugt.
...mit dieser Meinung, was den Code betrifft, bin ich nicht allein.
Erst Recht, da wir hier auch Programmierneueinsteiger haben und die auch die Threads lesen, halte ich es für wichtig, das man die alten "Programmiermuster" nicht noch als Copy/Paste Muster zur Verfügung stellt.

@Helmi:
Alles Gute...

@Daniel:
Ich bin mit der Entfernung des Beitrages einverstanden, aber es mußte mal raus. :?


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:07 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz