AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi TAdoQuery Parameters.DataType ändert sich nach SQL.Add
Thema durchsuchen
Ansicht
Themen-Optionen

TAdoQuery Parameters.DataType ändert sich nach SQL.Add

Ein Thema von berens · begonnen am 23. Jan 2025 · letzter Beitrag vom 24. Jan 2025
Antwort Antwort
berens

Registriert seit: 3. Sep 2004
435 Beiträge
 
Delphi 10.4 Sydney
 
#1

TAdoQuery Parameters.DataType ändert sich nach SQL.Add

  Alt 23. Jan 2025, 15:45
Datenbank: Access .mdb • Version: - • Zugriff über: TAdoConnection
Edit: Diesen Beitrag 1:1 bei ChatGPT liefert dann doch eine sinnvolle Antwort. Der Wert TAdoQuery.Paramcheck ist per definition Schuld daran:
Code:
Gibt an, ob die Parameterliste der ADO-Datenmenge neu erstellt wird, wenn sich zur Laufzeit die SQL-Anweisung ändert.
Gnaaa.

Thema damit erstmal ERLEDIGT, falls nicht jemand eine tolle idee hat, wie ich arbeiten kann, ohne jeden Parameter mit ".Create" manuell anzulegen...

Danke für eure Aufmerksamkeit, der Beitrag kann gerne gelöscht werden.

----

Hallo zusammen,
dank ChatGPT und Google bekommt man ja selbst immer mehr alleine gelöst, aber bei diesem Problem stehe ich vor einem Rätsel.

Hier seht ihr die gekürzte Methode, die so seit > 20 Jahren "Fehlerfrei" im Einsatz ist.
Fehlerfrei deswegen in Anführungszeichen, weil SPORADISCH die Exception "Datentypen in Kriterienausdruck unverträglich" kommt.
Nach langem hin und her kann ich es jetzt in diesem Moment gerade auf meinem PC dauerhaft reproduzieren, und habe dabei festgestellt,
dass durch die Ausführung von q.SQL.Add(' ORDER BY Termine.Von;') der q.Parameters.ParamByName('Jetzt1').DataType trotz der manuellen Festlegung auf ftDateTime auf ftWideString springt.

Das ist einerseits total unerwartet, da ich diesen oben explizt festgelegt habe. Andererseits wundert es mich, dass dieser Fehler dann nicht dauerhaft vorkommt.

Ich habe dazu auf die Schnelle nun im Internet keine "Einschränkungen" finden können, würde aber anhand des Fehlerbildes folgendende Erkenntnisse "definieren":
Code:
Der DataType der Parameter kann sich unerwartet, automatisch, und "ins Falsche" ändern, wenn nach der Zuweisung des Parameters mit "SQL.Add" weiterer SQL-Text hinzugefügt wird, oder wahrscheinlich auch, wenn der SQL.Text anderweitig geändert wird --> Parameter dürfen erst dann hinzugefügt werden, wenn der SQL-Text fertig ist!
Auch habe ich paranoide Bedenken, dass sich der DataTyp schon bei der Zuweisung von "Jetzt1" ändern könnte, wenn Delphi vielleicht der Meinung ist, einen besseren Datentyp zu finden, als den, den ich gebe (sonst würde es ja auch später nicht auf ftWideString springen... ).
q.Parameters.ParamByName('Jetzt1').DataType := ftDateTime;
q.Parameters.ParamByName('Jetzt1').Value := _Jetzt;
--> soll ich hier jetzt nochmal (oder stattdessen?) DataType := ftDateTime; machen?

Ist bekannt, WARUM oder durch welchen AUSLÖSER der DataType meines Parameters sich ändert, bzw. ist es normal, dass das bei q.SQL.ADD passiert, dass den Parametern ein neuer Datentyp zugeordnet werden könnte?
Ist dazu irgendwas dokumentiert, wonach muss ich suchen?

Oder ist das wieder so ein Programmierer-Moment nach dem Motto: "Entschuldigung, das steht auf der ersten Seite des Handbuchs von TAdoQuery, dass man nach dem Zuweisen der Parameter den SQL-Text nicht mehr verändern darf?".

Da ich im realen Programm das Query ein wenig komplexer Aufbauen muss, mit vielen Wenn-Danns, die sich auf einzelne Abschnitte und die Anzahl der Parameter sehr stark auswirken, wäre es fatal falls dies tatsächlich erwartet wird. Erst mit allen Wenn-Danns den SQL-Text verfassen, und dann erst mit allen Wenn-Danns die Parameter zu setzen scheint mit etwas ... abstrus? Bin ich der einzige Programmierer der das SQL-Query über mehrere Methoden verteilt zusammensetzen lässt (Füge Filter nach Auswahl des Benutzer hinzu; Füge Sortierung nach Auswahl des Benutzers hinzu, ...)?

Delphi-Quellcode:
procedure Database_SELECT_ALL_FROM_Termine_Jetzt(q: TAdoQuery; _Jetzt: TDateTime);
var
  t: string;
begin
  if not assigned(q) then Exit;

  try
    CloseQueryAndClearSQLTextAndParameters(q);

      t := ' SELECT *' +
           ' FROM Termine' +
           ' WHERE '                                   + #13#10 +
           ' ( Termine.EinblendZeit <= :Jetzt1 ) ' + #13#10 +
           ' AND '                                 + #13#10 +
           ' ( Termine.AusblendZeit > :Jetzt2 ) ';

      q.SQL.Add(t);

      q.Parameters.ParamByName('Jetzt1').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt1').Value := _Jetzt;

      q.Parameters.ParamByName('Jetzt2').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt2').Value := _Jetzt;

    q.SQL.Add(' ORDER BY Termine.Von;');

    OpenQueryAndLogIfFailed(q, P);
  except
//...
  end;

  if not q.Active then begin
    Clipboard.AsText := q.SQL.Text;
    sleep(0);
  end;
end;
Delphi 10.4
Delphi 10.4 32-Bit auf Windows 10 Pro 64-Bit, ehem. Delphi 2010 32-Bit auf Windows 10 Pro 64-Bit

Geändert von berens (23. Jan 2025 um 15:59 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.529 Beiträge
 
Delphi 7 Professional
 
#2

AW: TAdoQuery Parameters.DataType ändert sich nach SQL.Add

  Alt 23. Jan 2025, 17:45
Grundsätzlich baue ich zuerst das SQL vollständig zusammen und dann werden die Parameter mit Werten befüllt. Ich käme nie auf die Idee ein SQL teilweise zu erstellen, dann Parameter zu befüllen und dann das SQL zu erweitern ...

Daher hab' ich das von Dir beschriebene Problem wohl auch noch nie gehabt.
Delphi-Quellcode:
  try
    CloseQueryAndClearSQLTextAndParameters(q);

      t := ' SELECT *' +
           ' FROM Termine' +
           ' WHERE '                               + sLineBreak +
           ' ( Termine.EinblendZeit <= :Jetzt1 ) ' + sLineBreak +
           ' AND '                                 + sLineBreak +
           ' ( Termine.AusblendZeit > :Jetzt2 ) ';

      q.SQL.Add(t);
      q.SQL.Add(' ORDER BY Termine.Von;');

      q.Parameters.ParamByName('Jetzt1').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt1').Value := _Jetzt;
      q.Parameters.ParamByName('Jetzt2').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt2').Value := _Jetzt;
    OpenQueryAndLogIfFailed(q, P);
  except
//...
  end;
Wobei nicht einfach so?
Delphi-Quellcode:
      q.SQL.Add(' SELECT *');
      q.SQL.Add(' FROM Termine');
      q.SQL.Add(' WHERE ');
      q.SQL.Add(' ( Termine.EinblendZeit <= :Jetzt1 ) ');
      q.SQL.Add(' AND ');
      q.SQL.Add(' ( Termine.AusblendZeit > :Jetzt2 ) ');
      q.SQL.Add(' ORDER BY Termine.Von;');

      q.Parameters.ParamByName('Jetzt1').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt1').Value := _Jetzt;
      q.Parameters.ParamByName('Jetzt2').DataType := ftDateTime;
      q.Parameters.ParamByName('Jetzt2').Value := _Jetzt;
Dürfte jetzt auch nicht unbedingt schlechter wartbar sein oder unübersichtlicher.

Gut, wenn es eine Funktion oder Prozedur ist und T von außen kommt, dann ist
Delphi-Quellcode:
      q.SQL.Add(t);
      q.SQL.Add(' ORDER BY Termine.Von;');
schon ok.

Aber nichtsdestotrotz: Parameter erst befüllen, wenn das SQL fertig ist, dann gibt es keinen Grund für irgendeine Routine das SQL erneut zu parsen und dabei ggfls. eine andere Entscheidung bezüglich der Parametertypen treffen zu sollen können müssen.
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73
Online

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
769 Beiträge
 
#3

AW: TAdoQuery Parameters.DataType ändert sich nach SQL.Add

  Alt 24. Jan 2025, 18:28
Setz mal "ParamCheck" der Query auf false, bevor du das "Order-By-SQL" anhängst ...
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz