Einzelnen Beitrag anzeigen

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