SQLDB.pp sqoAutoCommit Bug?

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

Hallo,
ich glaube in der sqldb.pp einen Bug gefunden zu haben (der mir schon länger auf die Eier geht).
Ich habe in einem Projekt zwei SQLQuery. Mit der eine zeige ich Daten an und kann sie bearbeiten. Die Zweite benutze ich zum füllen der ersten.
zB so:

Code: Alles auswählen

  
  SQLQuery1.Options:=[sqoKeepOpenOnCommit,sqoAutoApplyUpdates,sqoAutoCommit,sqoRefreshUsingSelect];  
  SQLQuery2.Close;
  SQLQuery2.SQL.Clear;
  SQLQuery2.SQL.Append('SELECT distinct CURRENCY FROM COUNTRY');
  SQLQuery2.Open;
  while not SQLQuery2.EOF do begin
    SQLQuery1.AppendRecord([SQLQuery2.Fields[0].AsString, 'Yuan']);
    SQLQuery2.Next;
  end;              
nach dem ersten Durchlauf der while Schleife haut es mir die SQLQuery2 mit
Operation cannot be performed on an inactive dataset.
raus.
Ich denke der Fehler ist in der sqldb.pp (Lazarus Verion 3.99) Zeile 3273 : SQLTransaction.Commit;
Es sollte heißen: SQLTransaction.CommitRetaining;
Ich habe ein Beispiel Projekt angehängt.
Bevor ich einen Bugreport schreibe wäre es mir recht wenn ein erfahrener Entwickler drüber schauen könnte.
Ich habe das den Bug nur unter Linux, nur mit Firebird und nur Lazarus 2.2.6 und 3.99 getestet
Es geht um den Bereich in der sqldb.pp:

Code: Alles auswählen

procedure TCustomSQLQuery.ExecSQL;

begin
  CheckPrepare;
  try
    Execute;
    // Always retrieve rows affected
    FStatement.RowsAffected;
    If sqoAutoCommit in Options then
      SQLTransaction.Commit;
  finally
    CheckUnPrepare;
    // if not Prepared and (assigned(Database)) and (assigned(Cursor)) then SQLConnection.UnPrepareStatement(Cursor);
  end;
end;

procedure TCustomSQLQuery.ApplyUpdates(MaxErrors: Integer);
begin
  inherited ApplyUpdates(MaxErrors);
  If sqoAutoCommit in Options then
    begin
    // Retrieve rows affected for last update.
    FStatement.RowsAffected;
    SQLTransaction.Commit;
    end;
end;                                  
Ob das Commit in TCustomSQLQuery.ExecSQL in CommitRetaining geändert werden sollte, kann ich nicht beuteilen
Dateianhänge
project1.zip
(140.08 KiB) 57-mal heruntergeladen
Konrad

www.KoBraSoft.de

charlytango
Beiträge: 845
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von charlytango »

ohne jetzt dasProjekt im Detail angesehen zu haben.

Mir erschließt sich nicht warum ich mit einer Query eine andere befüllen soll die dann gleich aussieht???
Warum nicht gleich mit SQLQuery1 arbeiten?

Aus dem Bauch heraus würde mir in der Schleife ein .Post und ein .ApplyUpdates fehlen.
Nach einer kleinen Recherche macht aber AppendRecord bereits ein .Post (dataset.inc line897)

Code: Alles auswählen

while not SQLQuery2.EOF do begin
    SQLQuery1.AppendRecord([SQLQuery2.Fields[0].AsString, 'Yuan']);
    //SQLQuery1.Post;
    SQLQuery1.ApplyUpdates;
    SQLQuery2.Next;
  end;

charlytango
Beiträge: 845
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von charlytango »

Extempore Begin
Das Beilegen eines Testprojektes verdient einen großen Pluspunkt.
Das Benutzen von Interbase/Firebird zieht diesen wieder ab.
Ein Testprogramm für DB-Zugriffe ohne Datenbankinhalt ist ebenfalls recht sinnfrei.

Deswegen konnte ich das Testprojekt nicht laufen lassen.
Meiner unmaßgeblichen Meinung nach wäre für so ein Testprojekt SQLite die Datenbank der Wahl -- da muss niemand etwas installieren und findet auf jedem OS auch irgendwo die nötigen Zugriffsbibliotheken. Und die DB kannst du im Code erstellen oder mitliefern.
Extempore Ende.

Wenn ich das alles richtig verstehe schreibt dir .AppendRecord die Daten mit einem .Post in die Puffertabelle von TSQLQuery. Da ist noch weit und breit kein Commit drin das die Daten in der DB fixiert.
Vor einem Commit müssen die Daten erst in die DB (genauer: den DB Puffer) geschrieben werden.

Das passiert erst im ApplyUpdates wenn ich nicht ganz falsch liege. Und hier erfolgt dann auch implizit das ausstehende Commit.

Und die Meldung "Operation cannot be performed on an inactive dataset" ist IMHO korrekt. Denn SQLQuery1 wird weder in der Komponente noch im Code irgendwo geöffnet.

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

charlytango hat geschrieben:
Di 12. Sep 2023, 19:12
Mir erschließt sich nicht warum ich mit einer Query eine andere befüllen soll die dann gleich aussieht???
Das ist nur zu Demozwecken. In meinen echten Anwendungen ist das anders und sehr viel komplexer. Die Demo ist so einfach wie möglich und nur zur Veranschaulichung gedacht
charlytango hat geschrieben:
Di 12. Sep 2023, 19:32
Das Benutzen von Interbase/Firebird zieht diesen wieder ab.
Muss ich dafür rechtfertigen Firebird zu benutzen?
Außerdem weis ich nicht ob dieser Bug auch mit anderen DBs auftritt.
charlytango hat geschrieben:
Di 12. Sep 2023, 19:32
Ein Testprogramm für DB-Zugriffe ohne Datenbankinhalt ist ebenfalls recht sinnfrei.
Meinst Du damit das ich die "employee" Beispieldatenbank nicht mit gesendet habe. Ich bin davon ausgegangen, dass die allgemein bekannt ist. Jedenfalls kann man sie leicht googlen.
charlytango hat geschrieben:
Di 12. Sep 2023, 19:32
Wenn ich das alles richtig verstehe schreibt dir .AppendRecord die Daten mit einem .Post in die Puffertabelle von TSQLQuery. Da ist noch weit und breit kein Commit drin das die Daten in der DB fixiert.
Vor einem Commit müssen die Daten erst in die DB (genauer: den DB Puffer) geschrieben werden.

Das passiert erst im ApplyUpdates wenn ich nicht ganz falsch liege. Und hier erfolgt dann auch implizit das ausstehende Commit.
Und deshalb sind die Optionen sqoKeepOpenOnCommit,sqoAutoApplyUpdates,sqoAutoCommit gesetzt, die das automatisch machen.
Natürlich kann man das auch manuell machen. Hat oft auch Sinn. Aber es gibt diese Automatik, die oft auch sehr hilfreich ist. Dann soll sie aber auch funktionieren.
Konrad

www.KoBraSoft.de

charlytango
Beiträge: 845
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von charlytango »

KoBraSoft hat geschrieben:
Di 12. Sep 2023, 20:18
Muss ich dafür rechtfertigen Firebird zu benutzen?
Nein, absolut nicht.
Aber dann kannst du auch nicht erwarten dass sich dann jemand diese Demo genauer ansieht. Angeblich soll es Leute geben die diese DB nicht wirklich mögen. Daher mein Vorschlag mit dem kleinsten gemeinsamen Nenner (SQlite).
KoBraSoft hat geschrieben:
Di 12. Sep 2023, 20:18
Meinst Du damit das ich die "employee" Beispieldatenbank nicht mit gesendet habe. Ich bin davon ausgegangen, dass die allgemein bekannt ist. Jedenfalls kann man sie leicht googlen.
That's the point...

Scheinbar sind wir nicht der gleichen Meinung was Ressourceneinsatz betrifft.
Let's agree to disagree -- bin raus

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

charlytango hat geschrieben:
Di 12. Sep 2023, 20:51
Angeblich soll es Leute geben die diese DB nicht wirklich mögen.
Das verstehe ich nicht. Ich verstehe dass viele (und zu denen gehöre ich auch) ihre Lieblingsdatenbank haben. Ich mag Firebird, da es wirklich stabil läuft. Es ist Open Source und weit verbreitet. Ich habe früher mit Paradox gearbeitet, das war eine Katastrophe.
Warum mögen diese Leute Firebird nicht?
Daher mein Vorschlag mit dem kleinsten gemeinsamen Nenner (SQlite).
Ich werde versuchen die winzige Demo auf SQLite umzustellen. Bisher kämpfe ich noch mit

Code: Alles auswählen

Can not load SQLite client library "libsqlite3.so"
Konrad

www.KoBraSoft.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von af0815 »

KoBraSoft hat geschrieben:
Di 12. Sep 2023, 21:56
Ich werde versuchen die winzige Demo auf SQLite umzustellen. Bisher kämpfe ich noch mit

Code: Alles auswählen

Can not load SQLite client library "libsqlite3.so"
Bist du unter Windows oder Linux ? Weil die Meldung deutet auf Linux hin.
Und unter Linux ist die Installation der Treiber sehr einfach (meist über apt/aptitude/apt-get)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

af0815 hat geschrieben:
Mi 13. Sep 2023, 07:15
Bist du unter Windows oder Linux ? Weil die Meldung deutet auf Linux hin.
Und unter Linux ist die Installation der Treiber sehr einfach (meist über apt/aptitude/apt-get)
Ja ist Linux (Xubuntu 22.04.3 LTS)
Die Treiber waren schon installiert. Die Installationsroutine hat den Treiber libsqlite3.so.0.8.6 nach /usr/lib/x86_64-linux-gnu/ und einen Link libsqlite3.so.0 darauf erstellt.
Da fpc nur nach libsqlite3.so sucht kam die Fehlermeldung.
Ich hab mit

Code: Alles auswählen

 sudo ln ./libsqlite3.so.0.8.6 ./libsqlite3.so
in der Konsole im Verzeichnis /usr/lib/x86_64-linux-gnu/ einen zusätzlichen Link erstellt.
Ein ähnliches Problem habe ich stets mir Firebird. Dort muss ich auf jedem neuen System mit

Code: Alles auswählen

sudo ln  /usr/lib/x86_64-linux-gnu/libfbclient.so.2 /usr/lib/x86_64-linux-gnu/libfbclient.so
ebenfalls einen zusätzlichen Link erstellen.
Für mich ist das lästige Mehrarbeit. Lazarus Neulinge werden häufig daran scheitern und sich von Lazarus abwenden.
Neues Problem:
Wenn ich https://www.sqlite.org/datatype3.html richtig verstehe, kennt SQLite nur "text" als Datentyp. Char und VarChar in "alter table" werden als text angelegt. Und in Lazarus im DBGrid als (memo) angezeigt.
Kann das wirklich sein?
Konrad

www.KoBraSoft.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von af0815 »

Leider muss man bei Linux oft die *-dev Pakete zusätzlich nehmen, da ansonsten wichtige Symlinks fehlen


Bezüglich der Datentypen, ja intern mappt SQLlite ziemlich viel auf Text. Aber du solltest bei der Tabelldefinition die richtigen Typen nehmen, diese werden später auch als Metadaten gesendet und machen das leben der Queries einfacher.

SQLlite ist nicht unbedingt die einfachste DB. Da hat meiner Meinung nach MS-SQL Express weniger Besonderheiten (Mucken) :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

af0815 hat geschrieben:
Mi 13. Sep 2023, 13:17
Leider muss man bei Linux oft die *-dev Pakete zusätzlich nehmen, da ansonsten wichtige Symlinks fehlen
Ein sqlite3-dev gibt es nicht (zumindest habe ich keines gefunden).
firebird-dev legt die Links nicht an
Konrad

www.KoBraSoft.de

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

Zurück zum eigentlichen Problem
Anbei eine Testversion mit sqlite. Es ist mein erstes Programm mit dieser db. Ich bitte um Nachsicht.
Dateianhänge
project1.zip
(140.92 KiB) 54-mal heruntergeladen
Konrad

www.KoBraSoft.de

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6217
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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von af0815 »

Auszug aus meiner Standardinstallation
sudo apt -y update
sudo apt -y upgrade
sudo apt -y full-upgrade
sudo apt -y autoremove
....
sudo apt install -y freetds-bin libsybdb5 libsqlite3-dev sqlite3
sudo apt install -y sqlitebrowser
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

af0815 hat geschrieben:
Mi 13. Sep 2023, 13:42
libsqlite3-dev
Die habe ich übersehen. Ich habe nach sqlite3-dev gesucht.
Konrad

www.KoBraSoft.de

KoBraSoft
Beiträge: 57
Registriert: So 6. Jun 2021, 09:57
OS, Lazarus, FPC: Winux (L 2.2.4 FPC 3.2.2)
CPU-Target: 64Bit 32 Bit
Kontaktdaten:

Re: SQLDB.pp sqoAutoCommit Bug?

Beitrag von KoBraSoft »

Hab den Bug Report geschrieben:
https://gitlab.com/freepascal.org/lazar ... sues/40508
Bin gespannt was rauskommt
Konrad

www.KoBraSoft.de

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: SQLDB.pp sqoAutoCommit Bug?

Beitrag von Sieben »

Sorry, dass ich ein bisschen spät bin jetzt... aber mit deinem Lösungsvorschlag hättest du den Fehler nicht behoben, sondern nur sozusagen umgekehrt, da so das Fehlen der Option sqoKeepOpenOnCommit bei gleichzeitigem sqoAutoCommit nicht mehr korrekt behandelt würde. Vor allem aber erscheint es mir auch nicht die entscheidende Stelle zu sein. Wenn du dir mal den Code von TSQLTransaction.Commit ansiehst, wird dort eine Methode CloseDatasets aufgerufen, die wiederum TSQLTransaction.AllowClose aufruft - und dort wird tatsächlich sqoKeepOpenOnCommit abgefragt und die Funktion sollte für eine TSQLQuery mit dieser Option False zurückgeben und so das Schliessen verhindern. Vielleicht magst du ja da noch mal reinschauen, ich hätte leider erst am WE Zeit dazu.

Antworten