Datenbank, Prozedure Parameter und ein Problem [gelöst]

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Datenbank, Prozedure Parameter und ein Problem [gelöst]

Beitrag von Levario »

Hallo Forum,

ich beschäftige mich damit in meinen Datenbank SQL.Text auf Parameter umzusteigen. Leider schlägt jeder Versuch fehl.

Meine eingesetzte Datenbank und Komponenten
  • Datenbank MariaDB-10, (XAMPP)
  • ZeosLIb (TZConnection, und TZQuery)
  • Lazarus IDE (TDataSource)


Ich habe nach diesem Beispiel von https://wiki.freepascal.org/SqlDBHowto eine Prozedure geschrieben.

Code: Alles auswählen

procedure Form2.FindCustomer(const TableName : string; const StrSearchField : String; const StrSearchText : String);
begin
    Form2.ZQuery4Kunden.SQL.Clear;

   with Form2.ZQuery4Kunden do
   Begin
      Form2.ZQuery4Kunden.Close;
      Form2.ZQuery4Kunden.SQL.Text := 'SELECT * FROM :TableName WHERE :StrSearchField LIKE :StrSearchText';
      Form2.ZQuery4Kunden.Open;
      Form2.ZQuery4Kunden.Refresh;
   end;
end;
Fehler:
sql error you have an error in your sql syntax; check the manual... near ' Null WHERE NULL LIKE NULL at line 1.
Ersetze ich die Select Abfrage durch:

Code: Alles auswählen

Form2.ZQuery4Kunden.SQL.Text := 'SELECT * FROM '+TableName+' WHERE '+StrSearchField+' LIKE ''%'+StrSearchText+'%'';';
klappt die Abfrage.

Ich möchte den Parameter der gesucht wird mit %:Parameter% ausstatten um den gesuchten String auch als Teil finden zu können.

Beispiel: Mustermann Gesellschaft für Solartechnik mbH

Ich möchte bei der Eingabe von Mustermann und bei der Eingabe von Solartechnik die passenden Datensätze finden.

Meine Fragen dazu:
  • Wie setzt man Parameter richtig ein und was benötigt man dazu?
  • Beispiel Eintrag unter uses oder wo liegen die Fehler in der Procedure?
  • Beispiele oder Anleitungen im Netz?
  • Bücher zum Thema?
  • Wie habt ihr es gelernt? Wo habt ihr euer Wissen her?
Vielen lieben Dank für eure Hilfe.
Zuletzt geändert von Levario am So 16. Aug 2020, 20:55, insgesamt 1-mal geändert.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von af0815 »

Ich habe Kurse besucht und nach HowTo gesucht.

https://wiki.freepascal.org/SQLdb_Tutorial2
https://wiki.freepascal.org/SqlDBHowto

Wenn du Parameter einsetzt, so kannst du dafür eine Query fix mit SQL ausstatten und nur die Parameter Werte ändern. Das hat auf Servern den Vorteil, das er das Vorkompilieren und Cachen kann.

Ich mache es so
SQL Text(e) setzten.
Parameter Createn
Parameter zuweisen
Query open oder execute (je nach SQL Type)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von Levario »

Die Syntax von Parametern in Abfragen ist je nach Datenbanksystem unterschiedlich, aber die Unterschiede werden von TSQLQuery behandelt. Ersetzen Sie die Werte in der Abfrage durch einen Doppelpunkt gefolgt vom Namen des Parameters, den Sie verwenden möchten. Zum Beispiel:

Code: Alles auswählen

Query.SQL.Text := 'insert into TBLNAMES (ID,NAME) values (:ID,:NAME);';
Bin grade bischen überfordert. Was habe ich da falsch gemacht in meinem Quellcode oben? Oder kann mariaDB, ZEOS das nicht?
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von Levario »

af0815 hat geschrieben:
So 16. Aug 2020, 08:43
Ich habe Kurse besucht und nach HowTo gesucht.

https://wiki.freepascal.org/SQLdb_Tutorial2
https://wiki.freepascal.org/SqlDBHowto

Wenn du Parameter einsetzt, so kannst du dafür eine Query fix mit SQL ausstatten und nur die Parameter Werte ändern. Das hat auf Servern den Vorteil, das er das Vorkompilieren und Cachen kann.

Ich mache es so
SQL Text(e) setzten.
Parameter Createn
Parameter zuweisen
Query open oder execute (je nach SQL Type)
Welche Kurse gibt es die noch?
Hast du für mich ein Beispiel wie du es machst? Die HowTo funktionieren bei mir nicht. Ich habe mir Kurse auf English auf Udemy angesehen für die Grundlagen. leider ist da alles ohne Datenbanken.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von af0815 »

Die Kurse waren speziell auf meine Fragen und Problemstellungen ausgerichtet und mit max. 2 Personen besetzt :-) = mehr oder minder Privattrainer, damals hauptsächlich für Delphi. Zusätzlich noch die ganzen MS-SQLServerkurse von der Implementation, Administrierung bis zur Optimierung der Abfragen.

Grundlegend kann man Bücher für D5-D7 herannehmen, die sich mit Datenbanken beschäftigen. Andreas Kosch, Doberenz & Kowalsky fällt mir dazu als Autoren ein.

Ua. wenn man berücksichtigt das Lazarus/FPC kein Delphi ist und es einem um erweiterte Grundlagen geht. Die Beispiele sind nur sehr bedingt direkt auf Lazarus lauffähig und sehr Windowszentriert. Allerdings wird hier ein sehr tiefer Einblick in die Treiberschichten geboten.
Andreas Kosch: Client/Server Datenbankentwicklung mit Delphi
Andreas Kosch: ADO und Delphi

Einfacher und allgemeiner waren die Bücher (Kochbücher) von Doberenz & Kowalsky.


-------

Parameter sind in erster Linie für Parameter zu verwenden. Nicht für eine Ersetzung von Tabellennamen und Spaltennamen. (Das funktioniert nur manchmal unter speziellen Umständen und nicht mit allen Servern, ist also nicht stabil und damit absolut zu vermeiden)

Beispiel wenn eine Query mit den entsprechnenden Parametern im Objektinspektor designed wurde
'SELECT'
' UserID,'
' Username,'
' Userpasswort'
' FROM ST_User'
'WHERE'
' Username = :Username AND'
' Userpasswort = :Passwort'
Und im Programmtext verwende ich das dann so

Code: Alles auswählen

procedure TUserManagementSQL.CheckUserAndPass(user, pass: String;
  var aUID: Integer; var ValidUser: Boolean; LoginAction: Boolean);
var
  myCon : TZConnection;
begin
  ValidUser:=false;
  aUID := 0;
  Q_Login.Active := False;
  Q_Login.ParamByName('Username').Value := UpperCase(user);
  Q_Login.ParamByName('Passwort').Value := pass;
  Q_Login.Active := True;
  Q_Login.First;
  IF NOT (Q_Login.EOF and Q_Login.BOF) then begin
    // if an result is here, the user and password is valid
    ValidUser:=True;
    aUID:= Q_Login.FieldByName('UserID').AsInteger;
  end;
  Q_Login.Active := False;
end;
oder dynamisch

Code: Alles auswählen

function TXX.GetStueckzahl(var AnzGute: Integer; var AnzSchl: Integer;var AnzGes: Integer): boolean;
var
  Q: TZQuery;
begin
  Q:= TZQuery.Create(nil);
  try
    Q.Connection:= self.Connection;
    Q.Active := False;
    Q.SQL.Clear;
    Q.SQL.Add('SELECT COUNT(*) as Gute FROM [dbo].[xxGute] where [DT] between :DatumVon and :DatumBis ');
     // Params
    Q.Params.Clear;
    Q.Params.CreateParam(ftDate,'DatumVon',ptInput);
    Q.Params.CreateParam(ftDate,'DatumBis',ptInput);
    Q.ParamByName('DatumVon').AsDateTime:= StartOfTheDay(FVonDatum);
    Q.ParamByName('DatumBis').AsDateTime:= EndOfTheDay(FBisDatum);
    Q.Active := True;
    Q.First;
    AnzGute:= Q.FieldByName('Gute').AsInteger;
    Q.Active := False;
    Q.SQL.Clear;
    Q.SQL.Add('SELECT COUNT(*) as Schl FROM [dbo].[xxSchl] where [DT] between :DatumVon and :DatumBis ');
     // Params
    Q.Params.Clear;
    Q.Params.CreateParam(ftDate,'DatumVon',ptInput);
    Q.Params.CreateParam(ftDate,'DatumBis',ptInput);
    Q.ParamByName('DatumVon').AsDateTime:= StartOfTheDay(FVonDatum);
    Q.ParamByName('DatumBis').AsDateTime:= EndOfTheDay(FBisDatum);
    Q.Active := True;
    Q.First;
    AnzSchl:= Q.FieldByName('Schl').AsInteger;
    AnzGes := AnzGute + AnzSchl;
  finally
    Q.Free;
  end;
end;
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von Socke »

Levario hat geschrieben:
Sa 15. Aug 2020, 23:09
Ich möchte den Parameter der gesucht wird mit %:Parameter% ausstatten um den gesuchten String auch als Teil finden zu können.
Du musst den Tabellennamen immer fest im SQL-String hinterlegen - hier kannst du keinen Parameter angeben. Parameter sind nur bei Daten (WHERE, INSERT, UPDATE) erlaubt, nicht bei der Tabellenstruktur.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von theo »

Code: Alles auswählen

procedure Form2.FindCustomer(const TableName : string; const StrSearchField : String; const StrSearchText : String);
begin
...
      Form2.ZQuery4Kunden.SQL.Text := 'SELECT * FROM :TableName WHERE :StrSearchField LIKE :StrSearchText';
...
end;
Hier hast du v.A. ein fundamentales Missverständnis darüber, wie Sprachen wie Pascal funktionieren.
Das hat erst einmal mit Datenbanken nichts zu tun.
Du gehst davon aus, dass deine Prozedurparameter irgendwie "magisch" in den String gelangen.
Solche "Magie" gibt es aber in Pascal nicht ( Gott sei Dank.).

Benutzeravatar
gladio
Beiträge: 217
Registriert: Sa 21. Jun 2014, 06:15
OS, Lazarus, FPC: Win10-64 - aktuelle Lazarus/FPC Standard-Edition
CPU-Target: 64Bit
Wohnort: Rügen

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von gladio »

Die ZQuery befindet sich auf Form2 ?
Dann kannst du erst mal den Code etwas entschlacken.
Alles, was da 'Form2' ist kann weg. Ebenfalls die Zeile mit 'wiht ... '

Code: Alles auswählen

procedure Form2.FindCustomer(const TableName : string; const StrSearchField : String; const StrSearchText : String);
begin
    ZQuery4Kunden.SQL.Clear;
    ZQuery4Kunden.Close;
    ZQuery4Kunden.SQL.Text := 'SELECT * FROM TABELLENNAME WHERE :StrSearchField LIKE :StrSearchText';
    //hier müsste die Zuweisung der Parameter hin
    ZQuery4Kunden.Open;
    ZQuery4Kunden.Refresh;
end;
Zuweisung der Parameter wird meistens so erledigt:
ZQuery4.ParamByName('StrSearchField').AsString:='DeinKriterium';

Wie schon vorher beschrieben, den Tabellennamen nicht als Parameter.

Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: Datenbank, Prozedure Parameter und ein Problem

Beitrag von Levario »

gladio hat geschrieben:
So 16. Aug 2020, 19:12
Die ZQuery befindet sich auf Form2 ?
Dann kannst du erst mal den Code etwas entschlacken.
Alles, was da 'Form2' ist kann weg. Ebenfalls die Zeile mit 'wiht ... '

Code: Alles auswählen

procedure Form2.FindCustomer(const TableName : string; const StrSearchField : String; const StrSearchText : String);
begin
    ZQuery4Kunden.SQL.Clear;
    ZQuery4Kunden.Close;
    ZQuery4Kunden.SQL.Text := 'SELECT * FROM TABELLENNAME WHERE :StrSearchField LIKE :StrSearchText';
    //hier müsste die Zuweisung der Parameter hin
    ZQuery4Kunden.Open;
    ZQuery4Kunden.Refresh;
end;
Zuweisung der Parameter wird meistens so erledigt:
ZQuery4.ParamByName('StrSearchField').AsString:='DeinKriterium';

Wie schon vorher beschrieben, den Tabellennamen nicht als Parameter.
Danke das habe ich nun verstanden, umgesetzt und es hat funktioniert. Thema für mich gelöst.

Auch allen anderen hier im Thread ein großen Dank für die schnelle Hilfe am Wochenende.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

Antworten