Seltsames Datenbankverhalten

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Hallo,

ich kämpfe schon zwei Tage mit einem eigenartigen Phänomen. Hier erstmal der Code:

Code: Alles auswählen

Procedure TForm2.Die_m_loeschen;
begin
    form1.ZConn1.ExecuteDirect('UPDATE tText SET Y1 = 0  ');
end;

Code: Alles auswählen

Procedure TForm2.Selektion_fixieren;
var
 mmm : string;
begin
  Form2.Die_m_loeschen// Habe dies im Laufe meiner Fehlersuche auch in eine extra Prozdur geschrieben, (nicht nötig)
  Form1.QText.First;
  while not Form1.QText.EOF do   
  begin                           
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m'// DB_Y1 ist ein Edit-Feld der Datenbank "TDBEdit"
     Form1.QText.Post;
     Form1.QText.Next;
  end;
end;         


Code: Alles auswählen

procedure TForm2.ausgabeClick(Sender: TObject);
begin
     Form2.Selektion_Zeigen (2)// 0:Sortierung nach Namen 1: nach Alter 2: nach Datum der Änderung
     Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount);
end;
Procedure TForm2.Selektion_Zeigen (aFlag : integer)// 0:Sortierung nach Namen 1: nach Alter 2: nach Datum der Änderung
var
   sss: string;
begin
     sss := 'Select * from tText WHERE Y1 = "m" ';
     if aFlag = 0 then sss := sss + 'ORDER BY UPPER(RTitel)' ;
     if aFlag = 1 then sss := sss + 'ORDER BY rDatumerstellt DESC' ;
     if aFlag = 2 then sss := sss + 'ORDER BY rDatumgeaendert DESC' ;
     Form1.QText.SQL.Clear;
     Form1.QText.SQL.Text := sss;
     Form1.QText.Open;
end;   


Ich habe das Ergebnis einer etwas komplizierteren Datenbankabfrage in einer Tabellenaufstellung (TDBGrid). Diese Selektion möchte ich aber später im Programm nochmal abrufen, wobei zu diesem späteren Zeitpunkt es aber nicht mehr so ohne weiteres möglich ist, diese Selektion nochmal zu generieren.

Deshalb folgendes Vorgehen. Es gibt in der benötigten Tabelle eine Spalte (column) "Y1". Zunächst schreibe ich in die gesamte Spalte "Y1" den Wert "0" rein. Dann gehe ich Schritt für Schritt die Tabellenaufstellung, die ich später nochmal aufrufen möchte, durch und schreibe in die Tabelle in die Spalte den Buchstaben "m" rein. Damit habe ich es später sehr leicht, meine exakte Selektion wieder aufzurufen.

Wenn ich nun schön der Reihe nach die obigen Prozeduren einzeln aufrufe, dann funktioniert alles prima.
Also:
1. Diese Procedur aufrufen: "Procedure TForm2.Selektion_fixieren;" Im SQLite-Studio sieht man sehr schön, dass überall da das "m" eingetragen wird, wo ich es hinhaben möchte.
2. Wenn ich nun beliebig später im Programm die Prozedur "procedure TForm2.ausgabeClick(Sender: TObject);" aufrufe, dann werden mir auch ganz wunderbar meine gewünschten Datenbankeinträge aufgelistet.

Seltsam ist nun folgendes: Wenn ich unmittelbar nach dem "'m'-Eintrag" in die Datenbank und innerhalb derselben Prozedur die Abfrage mache, dann funktioniert diese Abfrage nicht. Warum?

Also so:

Code: Alles auswählen

Procedure TForm2.Selektion_fixieren;
var
 mmm : string;
begin
  Form2.Die_m_loeschen;
  Form1.QText.First;
  while not Form1.QText.EOF do   
  begin                           
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m';
     Form1.QText.Post;
     Form1.QText.Next;
  end;
  Form2.Selektion_Zeigen ( 2 )// Hier also erfolgt der sofortige Aufruf, der oben per separater Prozedur erfolgt.
  Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount);
end;     


Danke schonmal!
Aliobaba

Die verwendete Datenbank ist SQLite.
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Hallo und einen Guten Morgen,

Sorry, wenn ich mich nochmal melde; Zwischenzeitlich (es ist 01:40 Uhr) konnte ich mein Problem nochmal ein wenig eingrenzen:

Offenbar führt das Beschreiben der Felder in der Spalte "Y1-4" mit einem Zeichen (hier "0") dazu, dass die Selektion in der DBGrid-Spalte nicht mehr richtig durchlaufen wird.
Wenn ich die Zeile1 (sh Code) irgendwo im Programm etwas früher abarbeiten lasse, dann wird der "Text: "m"" korrekt in die Datenbank geschrieben.
Wenn diese Zeile1 aber unmittelbar vorher in derselben Prozedur steht, dann erfolgt dieser Eintrag ("m") nicht.

Woran kann das liegen?

Aliobaba

Code: Alles auswählen

  form1.ZConn1.ExecuteDirect('UPDATE tText SET Y1 = 0 , Y2 = 0 , Y3 = 0 , Y4 = 0 ')// hier genannt: Zeile1
 
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m'// DB_Y1 ist ein Edit-Feld der Datenbank "TDBEdit" Spalte "Y1"
     Form1.QText.Post;
     Form1.QText.Next;
  end;
 
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6197
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: Seltsames Datenbankverhalten

Beitrag von af0815 »

Füge das Statement aus dem ExecuteDirect der Connection in eine normale Query und führe die Query direkt aus. Nicht das du das Buffermanagement der Komponenten beeinflusst durch den Wechsel zwischen Komponente und Direktzugriff über die Connection.

Andreas
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

af0815 hat geschrieben:Füge das Statement aus dem ExecuteDirect der Connection in eine normale Query ...

Danke, Andreas für die schnelle Antwort,

kannst Du mir dabei helfen wie Du das meinst?
Das geht aber doch nur in einer anderen Query als "QText" - also eine neue Query, z.B. "QText_xy" ?
Und wie fügt man dieses "ExecuteDirect" in eine Query ein?

Aliobaba

af0815 hat geschrieben:Nicht das du das Buffermanagement der Komponenten beeinflusst durch den Wechsel zwischen Komponente und Direktzugriff über die Connection.
So könnte ich mir das Entstehen dieses Fehlers auch vorstellen, Danke!
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Soner
Beiträge: 622
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Seltsames Datenbankverhalten

Beitrag von Soner »

Hier stimmt irgendwas ganz nicht. In dieser Reihenfolge machst du das:
1) Irgendwo selektierst du tText (Selektion_Zeigen) und zwar mit ' WHERE Y1 = "m" '
2) Danach setzt du tText.Y1=0
3) Und jetzt versuchst du mit der gleichen Query aus Punkt 1) tText.Y1=m zu setzen.
Das wird nie klappen, weil für die Abfrage aus Punkt 1. ist tText.Y1=m.
Es weiß nicht von der Aktion das du in Punkt 2) gemacht hast.
Damit es von der Änderungen mitbekommt muß du schließen und neu öffnen etwa so:

Code: Alles auswählen

 
Procedure TForm2.Selektion_fixieren;
var
 mmm : string;
begin
  Form2.Die_m_loeschen// Habe dies im Laufe meiner Fehlersuche auch in eine extra Prozdur geschrieben, (nicht nötig)
 
 //hier XXXXXXXXXXXXXXXXXXXX
 Form1.QText.Close;
 Form1.QText.Open;
 
  Form1.QText.First;
  while not Form1.QText.EOF do   
  begin                           
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m'// DB_Y1 ist ein Edit-Feld der Datenbank "TDBEdit"
     Form1.QText.Post;
     Form1.QText.Next;
  end;
end;   
 

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Danke, Soner,

dann habe ich mich missverständlich ausgedrückt, bitte entschuldige:

Als erstes setze ich Y1 auf 0, und zwar die gesamte Column, also alle Einträge in Y1
Dann selektiere ich die Texte in einer Abfrage (die aber nicht beliebig im Programm reproduzierbar ist)
Bei den selektierten Texten setze dann ich Y1 auf m
Und dann kann ich (in aller Ruhe) eine SQL-Abfrage nach diesem "m" machen.

Das funktioniert hervorragend, wenn ich dieses "0-Setzen" vorab irgendwo im Programm mache.
Es funktioniert aber nicht, wenn ich dies unmittelbar vor dem Schritt mache, mit dem ich bei den selektierten Texten das Y1 auf "m" setze.

Ich halte die Erklärung von "af0815" für recht einleuchtend. Es könnte am "Buffermanagement" liegen (was immer das ist). Es sieht wirklich so aus, dass - wenn ich die beschriebenen Schritte unmittelbar hintereinander mache - beim Durchlauf der selektierten Texte der 0-Eintrag irgendwie noch nicht im TDBEdit-Feld "vorliegt".

Wie gesagt, es funktioniert ja prima, wenn ich das 0-Setzen deutlicher vor dem m-setzen mache. Damit kann ich gut leben; mich interessiert halt ganz einfach, warum dieses Verhalten so ist und wie man handeln müsste, wenn es programmtechnisch nicht möglich wäre, dieses 0-Setzen bereits "im Vorfeld" zu machen.

Außerdem ginge Dein Vorschlag auch nicht, da man nach dem Schließen und wieder Öffnen der Datenbank die Query nochmal machen müsste. Und das geht kaum, da sich die Programmsituation zwischenzeitlich so geändert hat, dass man nicht mehr auf dasselbe Query-Ergebnis kommt.

Danke!
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Soner
Beiträge: 622
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Seltsames Datenbankverhalten

Beitrag von Soner »

Eigentlicht meint af0815 mit "Buffermanagement" dasselbe, diese Aussage stimmt laut deinem Code nicht:
Aliobaba hat geschrieben:Danke, Soner,

dann habe ich mich missverständlich ausgedrückt, bitte entschuldige:

Als erstes setze ich Y1 auf 0, und zwar die gesamte Column, also alle Einträge in Y1
Dann selektiere ich die Texte in einer Abfrage (die aber nicht beliebig im Programm reproduzierbar ist)
Bei den selektierten Texten setze dann ich Y1 auf m
Und dann kann ich (in aller Ruhe) eine SQL-Abfrage nach diesem "m" machen.
..


Schau her, lies meine Kommentare:

Code: Alles auswählen

 
Procedure TForm2.Selektion_fixieren;
var
 mmm : string;
begin
  //Form1.QText ist schon irgendwo schon gestartet, also die Ergebnisse liegen im DB-Buffer
 
  //hier machst du tText SET Y1 = 0
  Form2.Die_m_loeschen;
 
 //Form1.QText ist noch aktiv und es weiß nicht von Löschaktion von eine Zeile drüber
 //und du setzt gleich vom alten Auswahl  Form1.DB_Y1.Text:='m';
 //da aber hier laut dein Auswahl Form1.DB_Y1.Text immer gleich 'm' war
 //denkt ZQuery es wurde nichts geändert macht wahrscheinlich keine updates.
 //deshalb mußt du hier referesh machen, am einfachsten einmal die Query schließen und anschließend öffnen
 
  Form1.QText.First;
  while not Form1.QText.EOF do   
  begin                           
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m';
     Form1.QText.Post;
     Form1.QText.Next;
  end;
  Form2.Selektion_Zeigen ( 2 ) ;
  Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount);
end;   
 



Aliobaba hat geschrieben:...
Außerdem ginge Dein Vorschlag auch nicht, da man nach dem Schließen und wieder Öffnen der Datenbank die Query nochmal machen müsste. Und das geht kaum, da sich die Programmsituation zwischenzeitlich so geändert hat, dass man nicht mehr auf dasselbe Query-Ergebnis kommt.
..


Ich habe ja nicht gesagt Datenbank (TZConnection) schließen, sondern Auswahl(Form1.QText) refresh machen mit schließen und öffnen.
Wenn du das in DisableControls/Enablecontrols packst, bekommt der Benutzer nichtmal davon.
Und noch eins, man muß nicht jedesmal Sql neu setzen. Du kannst mit TZQuery.Close Auswahl schließen und nachher mit TZQuery.Open öffnen SQL-String geht nicht verloren.

Kennst du das, das ist ziemlich nützlich wenn man viel mit Datenbanken arbeitet.

Code: Alles auswählen

 
var AktuellePosition : TBookMark;
begin
 try
  AktuellePosition:=ZQuery1.Bookmark; //merken
 
  ZQuery1.DisableControls;   // TDBGrid und Andre DB-Controls sollen jezt nicht aktiviert werden
 
  //jetzt irgendetwas mit query machen z.b.
  ZQuery1.First;
  while not ZQuery1.EOF do begin
    //...
   ZQuery1.Next;
  end;
 
  // Position zurücksetzen, der Benutzer merkt dann nicht dass es gescrollt wurde
  // am besten im try-except weil falls was gelöscht kann Fehler auftreten, so passiert dann nichts.
   try
     ZQuery1.Bookmark:=AktuellePosition;
   except
     on E: Exception do ; //nichts machen
   end;
 
 finally
  ZQuery1.EnableControls;   // TDBGrid und Andre DB-Controls sollen jezt aktiviert werden
 end;
 
end;
 


Edit:

Du sagst ja ganz oben:
Aliobaba hat geschrieben:...

Wenn ich nun schön der Reihe nach die obigen Prozeduren einzeln aufrufe, dann funktioniert alles prima.
Also:
1. Diese Procedur aufrufen: "Procedure TForm2.Selektion_fixieren;" Im SQLite-Studio sieht man sehr schön, dass überall da das "m" eingetragen wird, wo ich es hinhaben möchte.
2. Wenn ich nun beliebig später im Programm die Prozedur "procedure TForm2.ausgabeClick(Sender: TObject);" aufrufe, dann werden mir auch ganz wunderbar meine gewünschten Datenbankeinträge aufgelistet.

...

Genau das machst du hier was ich meine. Erst bearbeiten (0 setzen), dann in procedure TForm2.ausgabeClick(Sender: TObject); neu laden (refresh).

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Vielen Dank für Deine Hilfe!

sh. bitte meine Kommentare

Code: Alles auswählen

Procedure TForm2.Selektion_sortieren_nach_Kriterien (aFlag : integer)// 0:Sortierung nach Namrn 1: nach Alter 2: nach Datum der Änderung
begin
                   // Das Abfrageergebnis einer Query liegt in einer TDBGrid vor
                   // Nun wird die Column Y1 vollständig auf "0" gesetzt
  form1.ZConn1.ExecuteDirect('UPDATE tText SET Y1 = 0  ');
                   // Jetzt wird NUR für die Datensätze in der TDBGrid das Feld auf "m" gesetzt
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin
     Form1.QText.Edit;
     Form1.DB_Y1.Text:='m'// DB_Y1 ist ein Edit-Feld der Datenbank "TDBEdit" Spalte "Y1"
     Form1.QText.Post;
     Form1.QText.Next;
  end;
  Form1.QText.Close;                                                    // Dein Vorschlag ? habe ich das richtig verstanden?
  Form1.QText.Open;                                                     // Dein Vorschlag ? habe ich das richtig verstanden? 
                  // Und jetzt wird der Datenbestand selektiert bzgl des Feldes Y1=m
  Form2.Selektion_Zeigen ( aFlag )// 0:Sortierung nach Namen 1: nach Alter 2: nach datum der Änderung
end;           
 
Procedure TForm2.Selektion_Zeigen (aFlag : integer)// 0:Sortierung nach Namen 1: nach Alter 2: nach datum der Änderung
var
   sss: string;
begin
     sss := 'Select * from tText WHERE Y1 = "m" ';
     if aFlag = 0 then sss := sss + 'ORDER BY UPPER(RTitel)' ;
     if aFlag = 1 then sss := sss + 'ORDER BY rDatumerstellt DESC' ;
     if aFlag = 2 then sss := sss + 'ORDER BY rDatumgeaendert DESC' ;
 
     Form1.QText.SQL.Clear;
     Form1.QText.SQL.Text := sss;
     Form1.QText.Open;
end;       


Das funktioniert! Jetzt passiert aber wieder etwas völlig Unerwartetes!!
Wenn ich diese Prozedur unmittelbar hintereinander mit einem "neuen Mausklick" auf einen entsprechenden Button ein zweites mal aufrufe, dann werden ALLE Datensätze angezeigt, obwohl in der TDBGrid die korrekt selektierten Datensätze angezeigt werden!? :|
Alles läuft korrekt, wenn dieses "UPDATE tText SET Y1 = 0 " schon vorher irgendwo im Programm gemacht habe. :cry:

Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

... tolle Sache, das mit dem "Bookmark" :) ... was es so alles gibt!
Danke!
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Soner
Beiträge: 622
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Seltsames Datenbankverhalten

Beitrag von Soner »

close/open sollte vor Form1.QText.First; stehen, aber weist du was mir auffällt, du selektierst in Selektion_Zeigen Datensätze mit "WHERE Y1 = "m" " nur jetzt mit close/open geht der Auswahl verloren.
Ich kann ohne ganze Zusammenspiel der Db-TAbellen und Query nicht viel sagen, sorry.

Mach das hier (Ich habe deine Kommentare gelöscht damit du meine Kommentare sehen kannst):

Code: Alles auswählen

 
Procedure TForm2.Selektion_sortieren_nach_Kriterien (aFlag : integer) ;
begin
  //du hast irgendwo  nach irgendwelche Kriterien Form1.QText ausgewählt, das ist uns unbekannt
 
 
  form1.ZConn1.ExecuteDirect('UPDATE tText SET Y1 = 0  ');
 
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin
     //mach doch direkt weil du  Form1.QText gleicht neu öffnest in  Form2.Selektion_Zeigen
     form1.ZConn1.ExecuteDirect('UPDATE tText SET Y1 = "m" WHERE  tTextID= '+Form1.QText.FieldbyName('tTextID').AsString);
     // tTextID ist der Name von Indexspalte der tText-Tabelle. Ich denke mal du hast so etwas in deiner TAbelle
 
     //Form1.QText.Edit;
     //Form1.DB_Y1.Text:='m';
     //Form1.QText.Post;
 
     Form1.QText.Next;
  end;
 
 
  Form2.Selektion_Zeigen ( aFlag ) ;
end;
 

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Moin, Soner,

Whow! 2:06 Uhr!
Bin heute den ganzen Tag nicht zu Hause und probiere Deine Vorschläge noch aus und melde mich auf jeden Fall wieder.
Hab auch noch eine deutlich elegantere Lösung im Kopf....
Trotzdem ist es seltsam, dass bei einem unmittelbar wiederholten Aufruf der Prozedur bei identischem Query-Ergebnis als Ausgangssituation ein unterschiedliches Ergebnis rauskommt :?: 8)

Einen schönen Tag noch!
Aliobaba
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Soner
Beiträge: 622
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Seltsames Datenbankverhalten

Beitrag von Soner »

Aliobaba hat geschrieben:Moin, Soner,

Whow! 2:06 Uhr!
Bin heute den ganzen Tag nicht zu Hause und probiere Deine Vorschläge noch aus und melde mich auf jeden Fall wieder.
Hab auch noch eine deutlich elegantere Lösung im Kopf....
Trotzdem ist es seltsam, dass bei einem unmittelbar wiederholten Aufruf der Prozedur bei identischem Query-Ergebnis als Ausgangssituation ein unterschiedliches Ergebnis rauskommt :?: 8)

Einen schönen Tag noch!
Aliobaba


Momentan bin ich schwer erkältet, schlafe den ganzen Tag, wenn mitten in der Tag aufwache, muss ich Zeit schinden damit ich weiterschlafen kann :D

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

Hallo Soner,

und werde bitte schnell wieder gesund! Hoffentlich geht es Dir schon besser!

Ich habe Deine Anregungen umgesetzt; funktioniert mit ein paar kleinen Änderungen gut.
Trotzdem ist nun auch meine neue Idee verwirklich - und die ist deutlich schneller:

Schau mal bitte (wenn es Dir wieder besser geht). Meine Anmerkungen wieder in den Kommentaren:


Code: Alles auswählen

Procedure TForm2.Selektion_sortieren_nach_Kriterien (aFlag : integer)// 0:Sortierung nach Namrn 1: nach Alter 2: nach datum der Änderung
begin
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ')// X5 entspricht dem Y1 von früher
  Form1.QText_ID_initialisieren; // Eine andere(!!) Query, die alle vorhandenen Datensätze enthält
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin     
   //  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = "5" WHERE  tTextID= ' + Form1.QText.FieldbyName('rID').AsString);
   //  hab's nur ein wenig umgeschrieben,da im ExecuteDirect Befehl keine Variablen stehen können (Weiß aber, was du meinst)
     Form1.QText.Edit;
     With form1.QText_ID do     // Qtext_ID  "_ID"!  // Das ist die andere Query, die ALLE Datenbankeinträge enthält (sonst geht es nicht)
     Begin
       SQL.Clear;
       SQL.Text := 'UPDATE tText SET X5 = "5" ';
       SQL.Add(' WHERE rID =:TxID');
       ParamByName('TxID').AsString :=  Form1.QText.FieldbyName('rID').AsString;
       ExecSQL;
    end;
    Form1.QText.Next;
  end;
  Form2.Selektion_Zeigen ( aFlag )// 0:Sortierung nach Namen 1: nach Alter 2: nach datum der Änderung
  Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount); //ab jetzt nur noch kleine programminterne Routinen
  Form2.GridTitel_Focus_geben;
  Form2.Check_gezeigten_Datensatz (1);
end;   


Code: Alles auswählen

Procedure TForm2.Selektion_Zeigen (aFlag : integer)// 0:Sortierung nach Namen 1: nach Alter 2: nach datum der Änderung
var
   sss: string;
begin
     sss := 'Select * from tText WHERE X5 = "5" ';
     if aFlag = 0 then sss := sss + 'ORDER BY UPPER(RTitel)' ;
     if aFlag = 1 then sss := sss + 'ORDER BY rDatumerstellt DESC' ;
     if aFlag = 2 then sss := sss + 'ORDER BY rDatumgeaendert DESC' ;
 
     Form1.QText.SQL.Clear;
     Form1.QText.SQL.Text := sss;
     Form1.QText.Open;
end

Mit obiger Prozedur funktioniert es sehr gut!

Hier nun mein "neues Werk" ; funktioniert viel schneller, da viel weniger Datenbankabfragen
Sehr vieles ist in der "Where"-Abfrage drinnen : 150 mal "or"!

Code: Alles auswählen

Procedure TForm2.Selektion_sortieren_nach_Kriterien_2 (aFlag : integer)// 0:Sortierung nach Namrn 1: nach Alter 2: nach Datum der Änderung
var
 nn : integer;
 AWhere : String;
begin
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  Form1.QText_ID_initialisieren; // Eine andere Query, die nun alle vorhandenen Datensätze enthält
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  nn := 0;
  AWhere := 'Where rID = "9"';     // IDVariable erzeugen  "9" wird (absichtlich) nie gefunden
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin
     nn := nn + 1 ;
     AWhere := AWhere + ' OR rID=' + Form1.QText.FieldbyName('rID').AsString;
          if ( nn = 150) or ( nn = Form1.QText.RecordCount )  then
          begin
             With form1.QText_ID do     // Qtext_ID  "_ID"!
             Begin
               SQL.Clear;
               SQL.Text := 'UPDATE tText SET X5 = "5" ' + AWhere ;
               ExecSQL;
            end;
            nn := 0;
            AWhere := 'Where rID = "9"';             // IDVariable erzeugen
          end;
  Form1.QText.Next;
  end;
  Form2.Selektion_Zeigen ( aFlag )// 0:Sortierung nach Namen 1: nach Alter 2: nach Datum der Änderung
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount);
  Form2.GridTitel_Focus_geben;
  Form2.Check_gezeigten_Datensatz (1);
end;   
 
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: Seltsames Datenbankverhalten

Beitrag von Aliobaba »

.... sorry! So stimmt's: :oops:

Code: Alles auswählen

Procedure TForm2.Selektion_sortieren_nach_Kriterien_2 (aFlag : integer)// 0:Sortierung nach Namrn 1: nach Alter 2: nach Datum der Änderung
var
 nn , mm : integer;  //!!  "mm" braucht man noch!
 AWhere : String;
begin
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  Form1.QText_ID_initialisieren; // Eine andere Query, die nun alle vorhandenen Datensätze enthält
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  mm := 0//!!
  nn := 0;
  AWhere := 'Where rID = "9"';     // IDVariable erzeugen  "9" wird (absichtlich) nie gefunden
  Form1.QText.First;
  while not Form1.QText.EOF do     // Die Text-ID's werden der Reihe nach aufgerufen
  begin
     nn := nn + 1 ;
     mm := mm + 1//!!
     AWhere := AWhere + ' OR rID=' + Form1.QText.FieldbyName('rID').AsString;
          if ( nn = 150) or ( mm = Form1.QText.RecordCount )  then    //!!
          begin
             With form1.QText_ID do     // Qtext_ID  "_ID"!
             Begin
               SQL.Clear;
               SQL.Text := 'UPDATE tText SET X5 = "5" ' + AWhere ;
               ExecSQL;
            end;
            nn := 0;
            AWhere := 'Where rID = "9"';             // IDVariable erzeugen
          end;
  Form1.QText.Next;
  end;
  Form2.Selektion_Zeigen ( aFlag )// 0:Sortierung nach Namen 1: nach Alter 2: nach Datum der Änderung
  form1.ZConn1.ExecuteDirect('UPDATE tText SET X5 = 0  ');
  Form2.Lb_Anzahl_DS_gezeigt.Caption := IntToStr(Form1.QText.RecordCount);
  Form2.GridTitel_Focus_geben;
  Form2.Check_gezeigten_Datensatz (1);
end;   
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Soner
Beiträge: 622
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Seltsames Datenbankverhalten

Beitrag von Soner »

So jetzt bin ich wieder aufgewacht :D
Wenn du das Problem gelöst hast, dann ist es gut.

Was mir auffält ist, du arbeitest in der Prozedur Selektion_sortieren_nach_Kriterien_2 die Query Form1.QText Zeile für Zeile ab. Hat die SQL-Anweisung eine Where-Teil?
Wenn es hat, dann würde ich diesen Where-Teil in einer String-Variable zwischenspeichern und verwenden, dann ginge es einfacher, etwa so:

Code: Alles auswählen

 
  form1.QText_ID.SQL.Text := 'UPDATE tText SET X5 = "5" WHERE ' + Where_Teil_Von_Form1_QText;
  form1.QText_ID.ExecSQL;
 

Dann sparts du, den Loop.

Antworten