Lazarus-Zeos-SQLite-Suchen

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Singlepin
Beiträge: 8
Registriert: Fr 28. Aug 2015, 17:00
OS, Lazarus, FPC: Windows 11 (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Lazarus-Zeos-SQLite-Suchen

Beitrag von Singlepin »

folgendes geht

Code: Alles auswählen

DM.ZQTitel.SQL.Add('SELECT * FROM audio WHERE(parentpath=:PWeg)and(filename LIKE :PFile)');
DM.ZQTitel.Params[0].AsString:='/home/meinName/media/USB/Arabella/';
DM.ZQTitel.Params[1].AsString:='Barry Ryan - Eloise.mp3';
das geht nicht

Code: Alles auswählen


DM.ZQTitel.SQL.Add('SELECT * FROM audio WHERE(parentpath=:PWeg)and(filename=:PFile)');
DM.ZQTitel.Params[0].AsString:='/home/meinName/media/USB/Englisch/';
DM.ZQTitel.Params[1].AsString:='France Gall - Poupée De Cire, Poupée De Son.mp3';
auch das geht nicht

Code: Alles auswählen

DM.ZQTitel.SQL.Add('SELECT * FROM audio WHERE(parentpath=:PWeg)and(filename LIKE :PFile)');
DM.ZQTitel.Params[0].AsString:='/home/meinName/media/USB/Englisch/';
DM.ZQTitel.Params[1].AsString:='France Gall - Poupée De Cire, Poupée De Son.mp3';
Meine Notlösung ist zur Zeit

Code: Alles auswählen

function SonderEx(s:String):String;
var
  i:Integer;
  se:String;
begin
i:=1;
se:='';
while i<=Length(s)do
 begin
 if ord(s[i])<$80
  then se:=se+s[i]
  else
   begin 
   se:=se+'_';
   inc(i);
   end;
 inc(i);
 end;
Result:=se;
end;

...
DM.ZQTitel.SQL.Add('SELECT * FROM audio WHERE(parentpath=:PWeg)and(filename LIKE :PFile)');
DM.ZQTitel.Params[0].AsString:='/home/klaus/media/USB/Englisch/';
DM.ZQTitel.Params[1].AsString:=SonderEx('France Gall - Poupée De Cire, Poupée De Son.mp3');
...
Das Ergebnis ist aber nicht eindeutig.
Ich nutze Zeos 7.2.14 und Lazarus 2.2.6
Mein Hexeditor sagt mir, daß in SQLite und auch in meinem Programm die Strings identisch sind.

Hat eine eine bessere Lösung?

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von gladio »

Hast du schon probiert, die beiden Zeichenketten, Pfad und Datei, vor der Suchabfrage in einen String umzuwandeln
und so nur mit einem Parameter zu arbeiten
und den Suchstring und den Vergleichsstring in eine einheitliche Schreibweise zu bringen (upper- oder lowercase).

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: Lazarus-Zeos-SQLite-Suchen

Beitrag von charlytango »

Meine Strategie so etwas einzugrenzen:

Zuerst immer nur EINEN Parameter verwenden - ich nehme an, der Pfad wird funktionieren
Wenn der "Übeltäter" identifiziert ist, versuche ich eine SQL Abfrage mit einem externen Programm (meines z.b ist HeidiSQL) abzusetzen, um zu prüfen ob es an der Datenbank oder an Lazarus/ZEOS liegt.
Der Grund kann auch in einer nicht passenden sqlite.dll bzw.so liegen.

Singlepin
Beiträge: 8
Registriert: Fr 28. Aug 2015, 17:00
OS, Lazarus, FPC: Windows 11 (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von Singlepin »

Danke für die Antworten.

Nachdem ich tagelang das Problem hatte geht es jetzt wie ich es schon hatte.
Verstehe wer will.

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

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von MmVisual »

Dieser Programmierstiehl ist sehr Fehlerträchtig. Als erstes, wenn man eine neue SQL Abfrage in eine TZQuery bekommen will muss man den alten Text Inhalt löschen und nicht einfach mit ".Add()" hinzu fügen. Das geht am einfachsten mit der ".Text := " Zuweisung:

Code: Alles auswählen

DM.ZQTitel.SQL.Text := 'SELECT ......'
Das zweite: Man sollte die Parametername nicht als Index nutzen sondern die echten Namen verwenden. Damit wird die Übergabe immer passend sein, egal wie komplex der SQL String ist, auch wenn man irgend wann mal die SQL Abfrage umbaut:

Code: Alles auswählen

DM.ZQTitel.ParamByName('PWeg').AsString
Wenn du das so umgebaut hast, schaue ob es funktioniert. Auch mehrere Parameter können problemlos verwendet werden.
Als Grundregel gilt:
Alle String, DateTime und Float Werte werden immer als Parameter übergeben, nur Integer Werte können mit einem einfachen i.ToString als Text gewandelt werden und im SQL verwendet werden.
Und sollte man z.B. einen Wert von einer anderen TZQuery/Feld wieder als Integer Zahl in SQL verwenden, dann sollte man immer so "QueryField.AsInteger.ToString" machen und niemals "QueryField.AsString", also direkte String Rückgabe, denn sollte einmal da ein "NULL" drin stehen wäre der String dann leer und mit AsInteger.ToString kommt wenigstens eine "0" zurückt und der SQL Befehl ist dann wieder gültig.

Wenn du diese paar Kleinigkeiten berücksichtigst hast du ca. 99,9% alle Anfängerprobleme beseitigt.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Singlepin
Beiträge: 8
Registriert: Fr 28. Aug 2015, 17:00
OS, Lazarus, FPC: Windows 11 (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von Singlepin »

Hallo MmVisual,

das bei meinen Codeschnipseln "Clear" davor und "Open" danach stehen habe ich voraus gesetzt.

Parameter über den Index anzusprechen ist Geschmackssache.
Beim Zugriff auf Datenbankfeldern ist "ParamByName" zu 99% die richtige Wahl, da würde ich dir zustimmen.

DM.ZQTitel.SQL.Text := 'SELECT ......' ist mir bei längeren SQL-Scripen zu unübersichtlich.

Der Tipp mit der Typumwandlung "QueryField.AsInteger.ToString" werde ich mir merken, da kann man bestimmt Fehler vermeiden.

Aber zurück zu meinem Problem, dabei geht es nicht darum ob es guter Stiehl ist.

Code: Alles auswählen

procedure TForm1.Button2Click(Sender: TObject);
begin
ZQuery1.SQL.Clear;
case Radiogroup1.ItemIndex of
 0:ZQuery1.SQL.Add('SELECT * FROM audio WHERE(parentpath="Daten/")AND(Filename="France Gall - Poupée De Cire, Poupée De Son.mp3")');
 1:ZQuery1.SQL.Add('SELECT * FROM audio WHERE(parentpath="Daten/")AND(Filename="ACDC - Hells Bells.mp3")');
 2:begin
   ZQuery1.SQL.Add('SELECT * FROM audio WHERE(parentpath=:Weg)AND(Filename=:Datei)');
   ZQuery1.Params[0].AsString:='Daten/';
   ZQuery1.Params[1].AsString:='France Gall - Poupée De Cire, Poupée De Son.mp3';
   end;
 3:begin
   ZQuery1.SQL.Add('SELECT * FROM audio WHERE(filename LIKE :PFile)and(parentpath=:PWeg)');
   ZQuery1.Params[0].AsString:='France Gall - Poupée De Cire, Poupée De Son.mp3';
   ZQuery1.Params[1].AsString:='Daten/';
   end;
 end;
ZQuery1.Open;
end;
Bei Variante 0 gibt es einen SQL-Logic error.
Bei Variante 1 nicht und der Datensatz wird gefunden schult ist offensichtlich das "é" in Variante 0
Bei Variante 2 wird der Datensatz nicht gefunden
und bei Variante 3 finden er den Datensatz

Damit ist mein Problem gelöst, aber wenn jemand Variante 2 benutzt tappt er in eine böse Falle.
Wer testet schon auf Bezeichnungen mit "é" oder anderen Zeichen. Das merkt man meist erst in der Praxis.
LIKE nimmt man eigentlich wenn kein eindeutiges Ergebnis erwartet wird.

Als Anlage mal alles zum Testen.
Dateianhänge
Test.zip
(143.03 KiB) 147-mal heruntergeladen

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

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von MmVisual »

DM.ZQTitel.SQL.Text := 'SELECT ......' ist mir bei längeren SQL-Scripen zu unübersichtlich.
Wenn man den ersten Teil des SQL Befehls als "DM.ZQTitel.SQL.Text := '..." macht spart man sich das .Clear.
Und durchaus kann man die folgende Zeilen mit "DM.ZQTitel.SQL.Add()" weiter machen.
Ich erzeuge zum Teil SQL Scripte mit über 50 Zeilen, natürlich mit Add und nicht alles in einer einzeigen Zeile.
Wer testet schon auf Bezeichnungen mit "é" oder anderen Zeichen.
Es gibt da noch viel mehr Zeichen die viel schlimmer sind. z.B. das "°" Zeichen, wenn da die Codierung nicht passt zerhaut dieses eine Zeichen den ganzen Text.
Daher ist es wichtig dass man Text immer per Parameter übergibt. Böse Jungs können ansonsten relativ leicht SQL Injections machen und ganz böse Sachen mit der Datenbank anstellen.
Bild1.png
Bild1.png (58.13 KiB) 4478 mal betrachtet
EleLa - Elektronik Lagerverwaltung - www.elela.de

Singlepin
Beiträge: 8
Registriert: Fr 28. Aug 2015, 17:00
OS, Lazarus, FPC: Windows 11 (L 2.0.12 FPC 3.2.0)
CPU-Target: 64Bit

Re: Lazarus-Zeos-SQLite-Suchen

Beitrag von Singlepin »

Gute Nachricht!

Mit Zeos 8.0.0 ist der Fehler behoben.

Antworten