Lazarus, MySQL, TSQLQuery

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
jjturbo
Beiträge: 5
Registriert: Do 27. Jul 2017, 13:06

Lazarus, MySQL, TSQLQuery

Beitrag von jjturbo »

Moin Forum,

ich hab eine Formular mit mit: TSQLConnector, TSQLQuery, TSQLTransaction, TDataSource, TDBGrid, TDBNavigator.
Ein Zugriff auf eine lokale (MySQL8) Datenbank auf eine Testtabelle funktioniert tadellos. Ich kann im DBGrid Daten einfügen und löschen.

Jetzt habe ich rechts daneben die gleichen Komponenten noch einmal platziert und verbinde mich mit derselben DB und schau in die gleiche Tabelle. Aber dort sehe ich nicht wenn man auf der linken Seite Daten geändert hat, auch nicht nach einem erneuten Absenden des SELECT Statements. Erst wenn ich die Connection kurz Active = false und anschliessend Active = True setze sehe ich die Änderungen nach einem erneutem SELECT. Wenn ich mir die Tabelle in der Workbench ansehe sind die Änderungen allerdings angekommen, also liegt das Problem irgendwo im Bereich der Aktualisierung der Daten.
Was mache denn wohl falsch?

jjturbo
Beiträge: 5
Registriert: Do 27. Jul 2017, 13:06

Re: Lazarus, MySQL, TSQLQuery

Beitrag von jjturbo »

Jetzt funktioniert es:
Query.Activ := false;
Query.SQL.Clear;
Query.SQL.SetText(SQL_STATEMENT);
Query.Active := True;

Sieben
Beiträge: 202
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.2.0, FPC 3.2.2
CPU-Target: i386

Re: Lazarus, MySQL, TSQLQuery

Beitrag von Sieben »

Es gibt drei Stufen, in denen Werte in die DB geschrieben werden:

- TSQLQuery.Post;
- TSQLQuery.ApplyUpdates;
- TSQLTransaction.Commit;

Post schreibt nur in den internen Buffer von TDataSet, mit der DB passiert noch nichts. Erst ein ApplyUpdates schickt die Werte an die DB, die sie zunächst mal sozusagen vorläufig einträgt. Für die Connection, in deren Rahmen das gemacht wird, sind sie danach - wie gesagt vorläufig - auch schon sichtbar und können, zB mit einer zweiten TSQLQuery an der gleichen Connection, auch abgefragt werden. Für alle anderen Prozesse nicht, dafür braucht es das Commit der TSQLTransaction. Erst dann sind die Werte endgültig und für alle Prozesse sichtbar geschrieben. Belässt du es bei den Standardeinstellungen der Komponenten, schliesst ein Commit auch alle Queries der aktuellen Connection um dir sozusagen zu signalisieren: gibt neue Daten, hol mal neu.

So wie du deine kleine App beschreibst, machst du das Post explizit mittels TDBNavigator bzw implizit, indem du die aktuell geänderte Zeile des TDBGrid verlässt. Aus deiner Beschreibung wird aber nicht so recht klar, was du in Bezug auf ApplyUpdates und Commit unternimmst. Mit den Standardeinstellungen dürfte so eigentlich nichts geschrieben werden, zumindest nicht endgültig...?

Michel
Beiträge: 35
Registriert: Sa 4. Dez 2021, 11:43
OS, Lazarus, FPC: Windows 10 / Ubuntu 20.04 LTS (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus, MySQL, TSQLQuery

Beitrag von Michel »

Ich habe folgendes erfolgreich getestet (alles nur "abstrakt", damit, man sieht welche Klasse berührt werden):

TSQLTransaction.Action:='caCommit'; // auch wenn laut Dokumentation das derzeit nicht berücksichtigt werden soll.
und ein
TSQLQuery.Options.sqoAutoApplyUpdates:=True; // Sorgt dafür dass nach dem TSQLQuery.ApplyUpdates ein TSQLTransaction.Commit nicht mehr notwendig ist, das betreffende Query aktiv bleibt und in anderen DB-Komponenten wie z.B. einem Grid die aktuellen Daten angezeigt werden.

Allerdings bin ich nicht der Lazarus-Experte, ich arbeite mich neu ein und auch als langjähriger Delphi-Nutzer erschließen sich mir bei Lazarus nicht alle Dinge bzw. Einstellungen. Ich bin noch in der Try-And-Error-Phase. :)

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Lazarus, MySQL, TSQLQuery

Beitrag von af0815 »

Wenn man 2 Queries auf dieselben Daten hat, so kann die zweite gar nicht mitbekommen das sich die Daten geändert haben, sprich, das diese Daten genaugenommen ungültig sein können. Es gibt keine Callbacks vom SQLServer zurück zu den DBKomponenten. Das muss man über die Logik der Programmierung lösen.

In dem Beispiel wo alles im selben Programm ist, kann man bei Änderungen der zweiten Query ja sagen, das sie sich die Daten neu holen muss.

Ansonsten ist Multiuser DB Programmierung schon ein Thema, wo man sich was im Vorfeld überlegen muss, bzw. auch auf Fehler im ApplyUpdates sauber reagieren kann. Noch dazu kann es den Effekt geben, das die letzte Änderung eine vorhergehende überschreiben kann, wenn zwei oder mehr am selben Datensatz eine Änderung vornehmen. Nicht umsonst kann es mehrere Isolationslevel von Datenabfragen geben.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Michel
Beiträge: 35
Registriert: Sa 4. Dez 2021, 11:43
OS, Lazarus, FPC: Windows 10 / Ubuntu 20.04 LTS (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus, MySQL, TSQLQuery

Beitrag von Michel »

Hmm, ok, hatte ich nicht so gelesen. Ich habe verstanden, dass mehrere DB-Komponenten sich eine DataSource sprich Query teilen und irgendwie die eine Komponente nicht mitbekommt, dass in der anderen Änderungen erfolgten. :?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Lazarus, MySQL, TSQLQuery

Beitrag von af0815 »

Michel hat geschrieben:
Di 19. Apr 2022, 15:50
Hmm, ok, hatte ich nicht so gelesen. Ich habe verstanden, dass mehrere DB-Komponenten sich eine DataSource sprich Query teilen und irgendwie die eine Komponente nicht mitbekommt, dass in der anderen Änderungen erfolgten. :?
EINE Query mit einer Datasource geht. Die Komponenten verständigen sich intern über Änderungen. Nur zwei Queries mit Datasourcen können sich nicht von selbst synchron halten, die beiden Queries wissen voneinander nichts (ausser master-detail Konstrukte)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Lazarus, MySQL, TSQLQuery

Beitrag von charlytango »

@Michael
Kann es sein dass da Begrifflichkeiten durcheinander gekommen sind?
af0815 hat geschrieben:
Sa 16. Apr 2022, 17:25
Wenn man 2 Queries auf dieselben Daten hat,
af0818 spricht von zwei Queries auf die selben Daten. Damit meint er wohl ZWEI Abfragen. (also zwei TQueries)

Du sprichst davon dass sich mehrere DB-sensitive-Komponenten eine Datasource teilen die wiederum von einer TQuery (bzw einem Äquivalent davon) befüllt wird.

Das sind unterschiedliche Paar Schuhe!!

Meiner Erfahrung nach wissen alle mit der gleichen Datasource verknüpften DB-Komponenten über Änderungen sofort Bescheid.

Änderst du aber mittels einer TQuery einen Kundennamen bekommt das die gleichzeitig offene zweite TQuery mit zb einer Kundenliste nicht automatisch mit.

Michel
Beiträge: 35
Registriert: Sa 4. Dez 2021, 11:43
OS, Lazarus, FPC: Windows 10 / Ubuntu 20.04 LTS (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus, MySQL, TSQLQuery

Beitrag von Michel »

Naja, ich habe wohl
Jetzt habe ich rechts daneben die gleichen Komponenten noch einmal platziert
eben nicht so interpretiert, dass er tatsächlich sämtliche zuvor aufgezählten Komponenten nochmals vollständig kopiert, iteriert und entsprechend neu mit identischen Datenbank verbunden hat. :oops:

Mir ist schon klar, dass zwei SQL-Querys eben auch zwei voneinander unabhängige Datenmengen sind, selbst wenn sie sich die identische Datenherkunft teilen.

Antworten