![]() |
Datenbank: MySQL • Version: 10.1.37 • Zugriff über: ODBC
ADO Query Parameter zur Laufzeit erstellen
Hallo zusammen!
Ich bin gerade etwas am Verzweifeln bei dem Versuch Parameter für eine ADOQuery zur Laufzeit zu erstellen. Ich nutzte Delphi 10.2. Das ERP-System sowie die App sind über ODBC angelegt. Die Beispiele sind etwas gekürzt und auf die wesentlichen Funktionen beschränkt. Ich habe mir eine Datenbank Unit erstellt und ein TDatabse Klasser erstellt, die von der TADOConnection erbt. Das gleiche mit einer TQuery Klasse, die von der TADOQuery erbt.
Code:
Die Konstruktoren sind wie folgt
TDatabase = class(TADOConnection)
constructor Create; reintroduce; private public function TryEstablishingConnection: Boolean; procedure SetConnectionToERP; procedure SetConnectionToApp; end; TQuery = class(TADOQuery) constructor Create; reintroduce; private public end;
Code:
Dann gibt es noch eine Unit für Einstellungen, die die Einstellungen in der MySQL-Datenbank setzten soll.
constructor TDatabase.Create;
begin inherited Create(nil); Self.LoginPrompt := False; Self.Mode := cmReadWrite; end; constructor TQuery.Create; begin inherited Create(nil); Self.EnableBCD := False; end; Die Funktion dafür lautet wie folgt
Code:
Debugge ich diese Anwendung koommt an der appUpdate.SQL.Text Zeile folgende Fehlermeldung
class procedure TEinstellung.SetzeTransferZeitpunkt(Nummer: Integer);
var appCon: TDatabase; appUpdate: TQuery; begin appCon := TDatabase.Create; appCon.SetConnectionToApp; if appCon.TryEstablishingConnection then begin appUpdate := TQuery.Create; appUpdate.Connection := appCon; appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = :appNummer'; appUpdate.Parameters.ParamByName('appNummer').Value := Nummer; try appUpdate.ExecSQL; except on E: Exception do begin appUpdate.Close; end; end; appUpdate.Close; FreeAndNiL(appUpdate); end; appCon.CloseConnection; FreeAndNil(appCon); end; Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitsbereiches oder sind miteinander unvereinbar Daraufhin habe ich die TQuery Klasse erweitert und den Aufruf bei den Einstellungen angepasst
Code:
Der Fehler blieb jedoch bestehen. Ich habe auch versucht appUpdate.Prepared := True; bzw. appUpdate.Prepared := False; vor dem setzten des SQL.Textes auszuführen.
TQuery = class(TADOQuery)
constructor Create; reintroduce; private public procedure AddIntegerParam(FieldName: String); end; procedure TQuery.AddIntegerParam(FieldName: string); begin Parameters.AddParameter.Name := FieldName; Parameters.ParamByName(FieldName).DataType := ftInteger; end; [Einstellungen] [...] appUpdate.AddIntegerParam('appNummer'); appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = :appNummer'; appUpdate.Parameters.ParamByName('appNummer').Value := Nummer; [...] Ohne eine Änderung. Nach einigem Suchen fand ich dann eine Funktion um Parameter mittels CreateParameter zu erzeugen und habe das in die AddIntegerParam Prozedur eingebaut.
Code:
Der Fehler bliebt jedoch weiterhin bestehen. Nach weiterem Suchen fand ich dann heraus, dass es manchmal Probleme geben kann und ich den Parameter in der Query in "" setzen soll.
procedure TQuery.AddIntegerParam(FieldName: string; Value: Integer);
begin Parameters.CreateParameter(FieldName, ftInteger, pdInputOutput, -1, Value); end; Dies habe ich entsprechend umgebaut zu
Code:
Dann sprang der Debugger weiter bis zur Zeile nach dem setzen des SQL.Text.
appUpdate.AddIntegerParam('appNummer');
appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = ":appNummer"'; appUpdate.Parameters.ParamByName('appNummer').Value := Nummer; Hier erscheint nun die Fehlermeldung: Parameter appNummer nicht gefunden. Daher habe ich den Block erweitert, damit der SQL.Text nochmal geparst wird
Code:
Dies brachte allerdings auch keinen Erfolg, der Parameter kann noch immer nicht gefunden werden.
appUpdate.AddIntegerParam('appNummer');
appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = ":appNummer"'; appUpdate.Parameters.ParseSQL(appUpdate.SQL.Text, True); appUpdate.Parameters.ParamByName('appNummer').Value := Nummer; Hat noch jemand eine Idee was ich hier Probieren könnte? |
AW: ADO Query Parameter zur Laufzeit erstellen
Zum Testen habe ich das ganze mal in eine Formularanwenung verlegt. Dort war das selbe Problem.
Ich habe dann aufgehört die Query zur Laufzeit zu erzeugen und auf das Formular gelegt.
Code:
Der Fehler Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitsbereiches oder sind miteinander unvereinbar bestand jedoch weiterhin.
appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = :appNummer';
appUpdate.Parameters.ParamByName('appNummer').Value := Nummer; Dann habe ich auf dem Formular in der Query Komponente den Parameter von Hand eingetragen, den Wert weiterhin im Quellcode zugewiesen. Der Fehler bestand weiterhin. Er verschwand erst, nachdem ich den Query.Text nicht im Quellcode setzte sondern direkt über den Objektinspektor der TADOQuery Komponente. Das Value wird weiterhin zur Laufzeit gesetzt. Es funktioniert nun, allerdings ist es etwas umständlich für jede einzelne Query eine eigene Komponente anzulegen. |
AW: ADO Query Parameter zur Laufzeit erstellen
Bei den ADOs nutze ich immer Parameter. Die SQLs werden zur Laufzeit erstellt bzw. aus Konstanten übernommen. Das funktioniert problemlos, genauso, wie Du es ursprünglich vorhattest.
Parameter im SQL darf man aber nicht in "" setzen. Innerhalb der "" wird ein Parameter nicht mehr als solcher erkannt. Er wird dann zum Inhalt einer Stringkonstanten. Die Fehlermeldung Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitsbereiches oder sind miteinander unvereinbar ist eher ein Hinweis auf datenbankseitige Probleme, als auf Implementierungsfehler. Mir scheint, das die Nummer aus der Datenbank nicht typkompatibel zur Nummer aus Delphi ist. Von welchem Typ ist die Datenbankspalte Nummer? Von welchem Typ ist die Delphivariabel Nummer? |
AW: ADO Query Parameter zur Laufzeit erstellen
Der Wert der Variablen ist ein Integer, in der Prozedur wurde der Datentyp auf ftInteger gestellt.
Mit der ersten Methode so
Code:
und mit der zweiten so
procedure TQuery.AddIntegerParam(FieldName: string);
begin Parameters.AddParameter.Name := FieldName; Parameters.ParamByName(FieldName).DataType := ftInteger; end;
Code:
In der Komponente auf dem Formular ist genau das gleiche eingestellt, nur nicht von mir zur Laufzeit erstellt worden. Da klappt es problemlos.
procedure TQuery.AddIntegerParam(FieldName: string; Value: Integer);
begin Parameters.CreateParameter(FieldName, ftInteger, pdInputOutput, -1, Value); end; Die Spalte in der Datenbank ist ebenfalls Integer. Hier der CREATE-Code
Code:
`nummer` INT(11) NOT NULL,
|
AW: ADO Query Parameter zur Laufzeit erstellen
Mittels ADO-Komponenten über ODBC auf eine MySQL-Datenbank zugreifen.
Das ist m.E. das schlechteste was man machen kann. AFAIK musst du *irgendwelche* Einstellungen (ich glaub im ODBC-Treiber) vornehmen damit es halbwegs funktioniert. Genaueres kann nicht sagen, da wir ein paar € ausgeben um mit den Zugriff keinerlei Probleme zu haben -> ![]() Übrigens: Damit umgeht man auch die GPL-Falle von MySQL. So wie du zugreifst müssen deine Kunden, wenn du den Quellcode nicht offen legst MySQL-Lizenzen kaufen! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:49 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-2025 by Thomas Breitkreuz