Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception (https://www.delphipraxis.net/203496-tfdquery-parameter-like-anweisung-fuehrt-bei-zu-grosser-laenge-zu-exception.html)

AuronTLG 24. Feb 2020 10:27

Datenbank: Firebird • Version: 2.5 • Zugriff über: FireDAC

TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Moin,

Ich habe eine Suche, die per SQL-Anweisung in mehreren Feldern nach einem Suchbegriff sucht.
Um Ärger mit Sonderzeichen etc zu vermeiden, wollte ich diese SQL-Anweisung auf Parametergebrauch umstellen, bin dabei jedoch auf ein Problem gestoßen:

Nehmen wir an, es gibt in der Datenbank ein Feld "TEST", was ein VARCHAR(5) ist.
Führe ich die SQL-Anweisung
Code:
SELECT * FROM BLUB WHERE TEST LIKE '%1234567890%'
aus, so liefert das zwar nichts zurück, funktioniert aber problemlos.

Mache ich das ganze jedoch so,

Code:
SELECT * FROM BLUB WHERE TEST LIKE :TEST
Query.Params.ParamByName('TEST').DataType := ftString;
Query.Params.ParamByName('TEST').AsString := '%1234567890%
So wird folgender Fehler ausgegeben:

Zitat:

[FireDAC][Phys][FB]-345. Daten zu groß Variable [TEST]. Maximale Länge = [5], tatsächliche Länge = [12] Hinweis: Setzen sie TFDParam.Size auf einen größeren Wert
Mache ich das Ganze so,

Code:
SELECT * FROM BLUB WHERE TEST LIKE '%'||:TEST||'%'
Query.Params.ParamByName('TEST').DataType := ftString;
Query.Params.ParamByName('TEST').AsString := '1234567890
, so passiert dasselbe.

Setze ich manuell die Size des Parameters, so wird stattdessen diese Fehlermeldung geworfen:

Zitat:

[FireDAC][Phys][FB]Dynamic SQL Error SQL error code = -303
arithmetic exception, numeric overflow, or string truncation string right truncation
Es gäbe einen Workaround, nämlich per Copy den Parameter nur mit der maximalen Länge des Feldes zu besetzen, doch das würde ich gerne vermeiden, da ich zum Auslesen der Datenfeldgröße nämlich eine offene Query bräuchte, welche unnötig Rechenzeit frisst.

Meine Frage daher: Kennt jemand das Problem bzw hat eine Lösung dafür?

mkinzler 24. Feb 2020 10:32

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Wenn das Feld nur 5 Zeichen groß ist, kann ein Vergleichsstring mit 12 Zeichen Länge ja auch nicht gefunde werden.

haentschman 24. Feb 2020 10:38

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Moin...:P

Hast du das SQL im QT oder einer Query die auf die Form gepappt ist?
Zitat:

[FireDAC][Phys][FB]-345. Daten zu groß Variable [TEST]. Maximale Länge = [5], tatsächliche Länge = [12] Hinweis: Setzen sie TFDParam.Size auf einen größeren Wert
Bei auf die Form gepappt und Parameter ... kontrolliere im Parmeter dort die Größe. Das sieht nach Standard aus.

dataspider 24. Feb 2020 10:41

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Hi

Ich habe mit FDQuery (FireDac) noch nichts gemacht.
Aber wenn man vor dem Setzen des Parameter - Wertes ein Prepare macht, dann sollte der Parameter in Size dir korrekte Länge enthalten.
Dann könntest du den String ohne zusätzliche Abfrage auf die richtige Größe kürzen.
Mache Komponenten (z.B. IBO) generieren auch schon die Feldliste der Query nach dem Prepare.
Dann könnte man dor die Länge ermitteln.

Frank

hoika 24. Feb 2020 10:46

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Hallo,
was soll Dein LIKE eigentlich bringen?
Es ergibt doch immer NULL:
Meinst Du vielleicht IN ?.

PS:
Bei String-Länge in FB musst Du halt immer aufpassen,
dass die Suchstrings und Ergebnisstrings nicht zu lang sind.

AuronTLG 24. Feb 2020 11:06

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Zitat:

Wenn das Feld nur 5 Zeichen groß ist, kann ein Vergleichsstring mit 12 Zeichen Länge ja auch nicht gefunde werden.
Das ist nicht das Problem. Die Exception ist das Problem. Ohne Parameter wird einfach nichts gefunden, was ja auch richtig und in Ordnung ist. Mit Parameter knallt es aber.

Zitat:

Hast du das SQL im QT oder einer Query die auf die Form gepappt ist?
Ist eine im Quelltext erzeugte TFDQuery.

Zitat:

Ich habe mit FDQuery (FireDac) noch nichts gemacht.
Aber wenn man vor dem Setzen des Parameter - Wertes ein Prepare macht, dann sollte der Parameter in Size dir korrekte Länge enthalten.
Dann könntest du den String ohne zusätzliche Abfrage aud die richtige Größe kürzen.
Mache Komponenten (z.B. IBO) generieren auch schon die Feldliste der Query nach dem Prepare.
Dann könnte man dor die Länge ermitteln.
Ich habs mal gerade probiert, aber nach dem Prepare hat der entsprechende Parameter leider nicht automatisch die Größe des Datenfeldes und führt daher ebenfalls zur Exception.

Zitat:

Hallo,
was soll Dein LIKE eigentlich bringen?
Es ergibt doch immer NULL:
Meinst Du vielleicht IN ?.
Wie erwähnt ist es eine Suche über MEHRERE Felder. Dieses Feld ist nur eins davon. Dementsprechend liefert die Suche auch gegebenenfalls etwas zurück.

MEissing 24. Feb 2020 11:45

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Wie sieht den den Query Parameter aus?

Code:
 object FDQuery1: TFDQuery
    Left = 640
    Top = 216
    ParamData = <
      item
        Name = 'Test'
        DataType = ftString
        ParamType = ptInput
        Size = 12
      end>
  end

dataspider 24. Feb 2020 12:21

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mal schnell getestet...
Delphi-Quellcode:
  FDQuery2.Prepare;
  FDQuery2.Params[0].Size := 100;
  FDQuery2.Params[0].AsString := '%123456tttttttfff';
  FDQuery2.Open;
Im Debugger ist der Size des Param vor dem Open noch 100.
Das Feld bei mir ist 10.
Nach dem Open kommt dennoch der Fehler, dass nur 10 erlaubt ist...

Hier scheint FireDac restriktiver zu agieren als andere Komponenten.

[EDIT]
Allerdings ist bei mir FDQuery2.Params[0].Size nach dem Prepare korrekt auf 10 gesetzt.
Damit habe ich den Wert, den ich brauche!

Folgendes geht bei mir nun:
Delphi-Quellcode:
procedure TFrmMain.cxButton2Click(Sender: TObject);
begin
  FDQuery2.Prepare;
  FDQuery2.Params[0].AsString := Copy('%123456tttttttfff', 1, FDQuery2.Params[0].Size);
  FDQuery2.Open;
end;
Frank

AuronTLG 24. Feb 2020 13:55

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
So, ich habe einen Workaround gefunden, mit dem ich höchstwahrscheinlich gut leben kann:
Ich hole mir die Größe der Stringfelder einfach vorab mittels einer TFDMetaInfoQuery und überspringe die Suchschritte, bei denen das Datenfeld kleiner ist als der Suchbegriff. Damit ist das Problem gelöst und anscheinend sogar Performance gewonnen, da die Query schlanker ist und weniger Parameter gesetzt werden.


Ich hatte es vorher nochmal mit dem Prepare versucht, aber irgendwie wollte das bei mir nicht so richtig.
Von daher werde ich diese Lösung hier jetzt nochmal bisschen durchtesten, aber soweit scheint es hervorragend zu funktionieren.

HeZa 24. Feb 2020 21:39

AW: TFDQuery -> Parameter in LIKE-Anweisung führt bei zu großer Länge zu Exception
 
Zitat:

Zitat von AuronTLG (Beitrag 1458209)
So, ich habe einen Workaround gefunden, mit dem ich höchstwahrscheinlich gut leben kann:
Ich hole mir die Größe der Stringfelder einfach vorab mittels einer TFDMetaInfoQuery ...

Das scheint mir eine sichere, wenn auch aufwendige Lösung zu sein. Ich hatte das Problem auch mal (weiss aber nicht mehr, mit welcher DB und welchen Komponenten). Mir half damals folgendes
Code:
SELECT * FROM BLUB WHERE TEST||'' LIKE :TEST
Zur Performance kann ich jetzt nichts sagen, die ist aber je nach Ausdruck und Qualität des Query-Optimizers aber eh bescheiden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:34 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz