[offen] ZEOS TQuery und OnChange Probleme

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Benutzeravatar
Levario
Beiträge: 132
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 11 Pro , MacOS und Linux Mint (Version 3.4 for Windows 64 bit )
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

[offen] ZEOS TQuery und OnChange Probleme

Beitrag von Levario »

Ich habe eine Benutzeroblerfäche die Daten von Mitarbeitern speichern kann. Die DBEdit Felder speichern automatisch, wenn die Felder geändert werden.
Ein DBGrid zeigt alle Mitarbeiter. Ich möchte nun eine Suche einfügen und das Query aktualisieren. Da hierbei alle DBEditfelder aktualisiert werden, bekomme ich den Fehler: Dataset "%s" is not in an edit or insert state. Schalte ich das OnChange Ereignis ab funktioniert alles. Kann ich dieses Problem irgendwie umgehen?
Zuletzt geändert von Levario am Mi 28. Aug 2024, 13:42, insgesamt 2-mal geändert.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

paweld
Beiträge: 91
Registriert: So 11. Jun 2023, 16:01
OS, Lazarus, FPC: Lazarus trunk, FPC fixes

Re: ZEOS TQuery und OnChange Probleme

Beitrag von paweld »

Prüfen Sie zu Beginn der „OnChange“-Prozedur, welchen Status das DataSet hat, und wenn es sich nicht im Bearbeitungs- oder Hinzufügungsmodus befindet, beenden Sie die Prozedur.

Code: Alles auswählen

  if (ZQuery1.State <> dsEdit) and (ZQuery1.State <> dsInsert) then
    exit; 
Grüße / Pozdrawiam
paweld

Benutzeravatar
Levario
Beiträge: 132
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 11 Pro , MacOS und Linux Mint (Version 3.4 for Windows 64 bit )
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: ZEOS TQuery und OnChange Probleme

Beitrag von Levario »

Danke hat funktioniert die Klasse ist unter uses db. Sollte das hier noch jemand interessieren.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: [gelöst] ZEOS TQuery und OnChange Probleme

Beitrag von MmVisual »

Diese IF Abfrage benötigt man immer wieder und geht etwas eleganter:

Code: Alles auswählen

if Not (ZQuery1.State In [dsEdit, dsInsert]) then
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
Levario
Beiträge: 132
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 11 Pro , MacOS und Linux Mint (Version 3.4 for Windows 64 bit )
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von Levario »

Das löst leider ein weiteres Problem nicht. Bei einem Insert möchte ich alle Datenfelder leer haben bis auf die neue ID. Er legt mir aber einen leeren Datensatz an und weil die GUI nicht schnell genug mit kommt speichert er die alten Daten in den neuen Datensatz. Setze ich alle Felder auf leer löscht er die alten daten oder die neuen. Das macht wenig Sinn. Kann ich das auch irgendwie verhindern?
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

charlytango
Beiträge: 1084
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: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von charlytango »

Just my 3 cents....

Ein "stateless" Design bei dem man in jedem Moment alles ändern kann hat seine Tücken.
Dabei muss man sehr häufig in unterschiedlichsten Situationen den Status der Query berücksichtigen, wie MmVisual das schon skizziert hat
MmVisual hat geschrieben: Di 27. Aug 2024, 14:17

Code: Alles auswählen

if Not (ZQuery1.State In [dsEdit, dsInsert]) then
Das könnte dann schon hilfreich sein

Code: Alles auswählen

  TDataSetState = (dsInactive, dsBrowse, dsEdit, dsInsert, dsSetKey,
    dsCalcFields, dsFilter, dsNewValue, dsOldValue, dsCurValue, dsBlockRead,
    dsInternalCalc, dsOpening, dsRefreshFields);
Allerdings gehe ich den komplett umgekehrten Weg, der sich über die Jahre bewährt hat.

Solange sich die Query im Browse-Modus befindet, also diverse unterschiedliche SELECTs abgefragt werden (also quasi deine Mitarbeitersuche durchgeführt wird), sind bei mir alle editierbaren Felder gesperrt (also EinFeld.Enabled:=false;).
Dies wird noch unterstützt dadurch, dass die Eingabefelder auch eine andere Farbe haben, um zu kennzeichnen, dass eine Änderung nicht möglich ist.
Soll eine Änderung erfolgen, ist eine definierte Aktion des Benutzers nötig(zb Button, TDBNavigator).
Dann wird die Farbe auf den Editiermodus umgestellt, die Felder werden editierbar gemacht und im Gegenzug wird der Grid und die Filtereingabe gesperrt.

Aus diesem Stadium kommt der Benutzer nur heraus indem er speichert oder abbricht.
Diese Vorgehensweise hat auch den Vorteil, dass es definierte Punkte gibt an denen Aktionen wie Validierungen, Sperren der Daten im Netzwerkbetrieb, Änderungsprotokollierungen, ggfs Aktualisierungen anderer Benutzerfenster. Sperren der Eingabe bei Inaktivität etc etc. erfolgen können.
Levario hat geschrieben: Di 27. Aug 2024, 12:40 Die DBEdit Felder speichern automatisch, wenn die Felder geändert werden.
Ja schon, aber doch nicht sooo automatisch bzw ist das oft nicht gewünscht.
Die Kontrolle über den Zeitpunkt von

Code: Alles auswählen

DBQuery1.Post;
DBQuery.ApplyUpdates;
überlasse ich auch nur ungern der Query-Komponente. Diese Automatismen helfen enorm, trotzdem möchte ich in meinem Design darüber die Kontrolle haben. Wenn du mal länger debugged hast, warum die Daten nicht in der DB landen, dann weißt du warum.

Diese Strategie mag zwar in der GUI etwas OldSchool sein, vermeidet aber Bedienfehler der User.
Zudem lassen sich mit so einem Vorgehen EingabeControls, Grid und Fiulter modularisieren und ggfs auch wiederverwenden.

wie gesagt... Just My 3 cents

Benutzeravatar
Levario
Beiträge: 132
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 11 Pro , MacOS und Linux Mint (Version 3.4 for Windows 64 bit )
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von Levario »

charlytango hat geschrieben: Mi 28. Aug 2024, 17:35
Allerdings gehe ich den komplett umgekehrten Weg, der sich über die Jahre bewährt hat.

Solange sich die Query im Browse-Modus befindet, also diverse unterschiedliche SELECTs abgefragt werden (also quasi deine Mitarbeitersuche durchgeführt wird), sind bei mir alle editierbaren Felder gesperrt (also EinFeld.Enabled:=false;).
Dies wird noch unterstützt dadurch, dass die Eingabefelder auch eine andere Farbe haben, um zu kennzeichnen, dass eine Änderung nicht möglich ist.
Soll eine Änderung erfolgen, ist eine definierte Aktion des Benutzers nötig(zb Button, TDBNavigator).
Dann wird die Farbe auf den Editiermodus umgestellt, die Felder werden editierbar gemacht und im Gegenzug wird der Grid und die Filtereingabe gesperrt.
Ganz so hart war ich nicht, aber ich habe es ähnlich umgesetzt. Dachte vielleicht geht es ja auch anders.
Die großen machen es ja vor. Daten wie in Confluence oder Google Docs können ja auch von mehreren Nutzer genutzt und aktualisiert werden.

Die Lösung der anderen beiden habe ich probiert. Diese funktioniert nur eingeschränkt. Aktuell habe ich es erst einmal wieder rausgenommen und gespert.
Ich überlege grade ein autosave einzubauen, wenn die Maske verlassen wird oder alle X Sekunden. Hier sollte die Abfrage der Kollegen oben dann greifen.
Aber soweit bin ich nocht nicht. Teste es gerade
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Benutzeravatar
Andysg
Beiträge: 6
Registriert: Sa 31. Aug 2024, 20:44
OS, Lazarus, FPC: Linux Mint, L 3.4
CPU-Target: 64Bit
Wohnort: NRW

Re: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von Andysg »

Das Problem scheint, daß deine Zquery geöffnet ist.
Zquery.close;
Zquery.sql.text:='select * from table .......'; // evt. noch Hochkomma einfügen mit #39
Zquery.open;

Beispiel:
frmdaten.sqlBanken.SQL.Text:='select * from banken where bankleitzahl like ' + #39 + edtsuchen.text + '%' + #39;

Sicher gibt es noch professioneller Lösungen, aber das funktioniert.

Eine Abfrage ist nur ein Filter.
Glaube wenig, recherchiere alles; Denke selbst.

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von MmVisual »

Ich habe für mich gelernt dass man Strings niemals selbst quoten darf. Das erzeugt bei frei eingebbaren Texten immer Probleme in der Form von möglichen SQL Injections und damit schafft man sich ein schwerwiegendes Sicherheitsproblem.

Die einfache Regel: Strings werden immer als Parameter übergeben. Damit kümmert sich dann Zeos alleine darum dass eine SQL Injection nicht mehr möglich ist.
Beispiel:

Code: Alles auswählen

frmdaten.sqlBanken.SQL.Text:= 'select * from banken where bankleitzahl like ' + #39 + edtsuchen.text + '%' + #39; // << falsch

frmdaten.sqlBanken.SQL.Text:= 'select * from banken where bankleitzahl like :Par1 '; // << richtig
frmdaten.sqlBanken.ParamByName('Par1').AsString := edtsuchen.text + '%';
Man kann mehrere Parameter verwenden. Ein Parameter beginnt immer mit einem : gefolgt von dem Bezeichner den man mag.
Dabei sollte man unbedingt beachten dass vor dem : ein Leerzeichen steht und nach dem Parametername ebenfalls ein Leerzeichen.
Beispiel:
...= :Param )...
Also vor dem ) noch ein Leerzeichen setzen. Auch wenn der Parameter am Zeilenende steht, dann einfch noch ein Leerzeichen dahinter setzen.
Sonst hat unter Umständen Zeos Probleme das Ende des Parameters korrekt zu erkennen. Ich hatte dazu die Erfahrung schon gemacht dass es nicht immer ging, jedoch eingeschlossen in Leerzeichen hat nie Probleme bereitet.

Dazu noch die zweite Regel:
Datum / Uhrzeit übergibt man am besten ebenfalls als Parameter. Damit ist man das Problem der korrekten Formatierung los, das macht dann Zeos. Beispiel:

Code: Alles auswählen

frmdaten.sqlBanken.ParamByName('ParDatum').AsDateTime := Now;
Und wenn man mit Float Zahlen Probleme hat, dann macht man dies ebenfalls mit Float Zahlen:

Code: Alles auswählen

frmdaten.sqlBanken.ParamByName('ParZahl').AsFloat := 3.1415;
Eigentlich sind nur reine Integer Werte unkritisch direkt in SQL zu übergeben, alles andere ist besser als Parameter. Zum einen spart man sich damit zum Teil größere Aufwände zum Konvertieren, da das Zeos alles schon kann, zum anderen ist dann der Code automatisch kompatiebel zu allen Datenbanken die Zeos unterstützt.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
Andysg
Beiträge: 6
Registriert: Sa 31. Aug 2024, 20:44
OS, Lazarus, FPC: Linux Mint, L 3.4
CPU-Target: 64Bit
Wohnort: NRW

Re: [offen] ZEOS TQuery und OnChange Probleme

Beitrag von Andysg »

Klappt prima.
Danke!
Glaube wenig, recherchiere alles; Denke selbst.

Antworten