AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi ADO Query Parameter zur Laufzeit erstellen
Thema durchsuchen
Ansicht
Themen-Optionen

ADO Query Parameter zur Laufzeit erstellen

Ein Thema von Thaleilama · begonnen am 6. Apr 2019 · letzter Beitrag vom 6. Apr 2019
Antwort Antwort
Thaleilama

Registriert seit: 6. Apr 2019
3 Beiträge
 
#1

ADO Query Parameter zur Laufzeit erstellen

  Alt 6. Apr 2019, 12:21
Datenbank: MySQL • Version: 10.1.37 • Zugriff über: ODBC
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:
  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;
Die Konstruktoren sind wie folgt

Code:
  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;
Dann gibt es noch eine Unit für Einstellungen, die die Einstellungen in der MySQL-Datenbank setzten soll.
Die Funktion dafür lautet wie folgt

Code:
  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;
Debugge ich diese Anwendung koommt an der appUpdate.SQL.Text Zeile folgende Fehlermeldung
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:
  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;
[...]
Der Fehler blieb jedoch bestehen. Ich habe auch versucht appUpdate.Prepared := True; bzw. appUpdate.Prepared := False; vor dem setzten des SQL.Textes auszuführen.
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:
  procedure TQuery.AddIntegerParam(FieldName: string; Value: Integer);
  begin
    Parameters.CreateParameter(FieldName, ftInteger, pdInputOutput, -1, Value);
  end;
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.
Dies habe ich entsprechend umgebaut zu

Code:
  appUpdate.AddIntegerParam('appNummer');
  appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = ":appNummer"';
  appUpdate.Parameters.ParamByName('appNummer').Value := Nummer;
Dann sprang der Debugger weiter bis zur Zeile nach dem setzen des SQL.Text.
Hier erscheint nun die Fehlermeldung: Parameter appNummer nicht gefunden.
Daher habe ich den Block erweitert, damit der SQL.Text nochmal geparst wird

Code:
  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;
Dies brachte allerdings auch keinen Erfolg, der Parameter kann noch immer nicht gefunden werden.

Hat noch jemand eine Idee was ich hier Probieren könnte?

Geändert von Thaleilama ( 6. Apr 2019 um 18:59 Uhr)
  Mit Zitat antworten Zitat
Thaleilama

Registriert seit: 6. Apr 2019
3 Beiträge
 
#2

AW: ADO Query Parameter zur Laufzeit erstellen

  Alt 6. Apr 2019, 16:12
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:
  appUpdate.SQL.Text := 'UPDATE appeinstellungen SET zeit = CURRENT_TIMESTAMP WHERE nummer = :appNummer';
  appUpdate.Parameters.ParamByName('appNummer').Value := Nummer;
Der Fehler Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitsbereiches oder sind miteinander unvereinbar bestand jedoch weiterhin.

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.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#3

AW: ADO Query Parameter zur Laufzeit erstellen

  Alt 6. Apr 2019, 17:36
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?
  Mit Zitat antworten Zitat
Thaleilama

Registriert seit: 6. Apr 2019
3 Beiträge
 
#4

AW: ADO Query Parameter zur Laufzeit erstellen

  Alt 6. Apr 2019, 19:02
Der Wert der Variablen ist ein Integer, in der Prozedur wurde der Datentyp auf ftInteger gestellt.

Mit der ersten Methode so
Code:
  procedure TQuery.AddIntegerParam(FieldName: string);
  begin
    Parameters.AddParameter.Name := FieldName;
    Parameters.ParamByName(FieldName).DataType := ftInteger;
  end;
und mit der zweiten so

Code:
  procedure TQuery.AddIntegerParam(FieldName: string; Value: Integer);
  begin
    Parameters.CreateParameter(FieldName, ftInteger, pdInputOutput, -1, Value);
  end;
In der Komponente auf dem Formular ist genau das gleiche eingestellt, nur nicht von mir zur Laufzeit erstellt worden. Da klappt es problemlos.
Die Spalte in der Datenbank ist ebenfalls Integer. Hier der CREATE-Code

Code:
  `nummer` INT(11) NOT NULL,
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: ADO Query Parameter zur Laufzeit erstellen

  Alt 6. Apr 2019, 19:27
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 -> https://www.devart.com/dac.html

Ü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!
Windows Vista - Eine neue Erfahrung in Fehlern.
  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 11:32 Uhr.
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