Insert into funktioniert nicht

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Insert into funktioniert nicht

Beitrag von Sayawa »

Hallo Zusammen,

ich fange gerade mit dem Programmieren in lazarus an und habe nun folgendes Problem bei dem Insert into eine MySQL Datenbank (Maria DB)

Ich habe folgenden Code und die Datenbankverbindung scheint zu funktionieren, ich bekomme zumindest keine Fehlermeldung hierzu, aber einen Eintrag in meiner Datenbank erhalte ich auch nicht.

Code: Alles auswählen

 
procedure ClearAllFields;
begin
     with FrmEQStamm do
     begin
          ComboBox1.Clear;
          ComboBox2.Clear;
          Edit1.Clear;
          Edit2.Clear;
          Edit3.Clear;
          Edit4.Clear;
          Edit6.Clear;
     end;
end;
 
procedure TFrmEQStamm.connectDB;
begin
     MySQL56Connection1.Hostname      := 'host';
     MySQL56Connection1.UserName      := 'user';
     MySQL56Connection1.Password      := 'pass';
     MySQL56Connection1.DatabaseName  := 'inventar';
     MySQL56Connection1.Transaction   := SQLTransaction1;
     MySQL56Connection1.Connected     := true;
     SQLQuery1.Database               := MySQL56Connection1;
end;
 
procedure TFrmEQStamm.Button1Click(Sender: TObject);
var
   // Variablen Deklaration
   strPC_Index, strGeraet, strHersteller, strModell, strSNr, strMACAdresse, strInvNr, strDatumEintrag, strAnschaffungsdatum, strLieferscheinnr : string;
 
begin
 
     //Variablen mit Inhalt füllen
     strPC_Index          := '1';
     strGeraet            := ComboBox1.Text;
     strHersteller        := ComboBox2.Text;
     strModell            := Edit1.Text;
     strSNr               := Edit2.Text;
     strMACAdresse        := Edit3.Text;
     strInvNr             := Edit5.Text;
     strDatumEintrag      := FormatDateTime('dd.mm.yyyy', now);
     strAnschaffungsdatum := Formatdatetime('dd.mm.yyyy', DateTimePicker1.date);
     strLieferscheinnr    := Edit6.Text;
 
 
     //Datenbankverbindung aufbauen
     FrmEQStamm.connectDB;
 
     FrmEQStamm.SQLQuery1.SQL.Add('INSERT INTO pc_geraete (pc_index, geraet, hersteller, modell, seriennummer, macadresse, inventarnummer, angelegt_am, anschaffungsdatum, lieferscheinnummer) VALUES('''+strPC_Index+''', '''+strGeraet+''', '''+strHersteller+''', '''+strModell+''', '''+strSNr+''', '''+strMACAdresse+''', '''+strInvNr+''', '''+strDatumEintrag+''', '''+strAnschaffungsdatum+''', '''+strLieferscheinnr+''')');
     FrmEQStamm.SQLQuery1.ExecSQL;
     //Bestätigungsnachricht bei Eintrag
     ShowMessage('Folgender Datensatz wurde angelegt:');
 
     //Felder wieder leeren
     ClearAllFields;
 
end;           


Ich habe es auch schon mit Parametern versucht, aber auch dort keine Fehlermeldung, aber auch kein Eintrag in der Datenbank. Habe ich etwas übersehen oder vergessen?
Zuletzt geändert von m.fuchs am Do 26. Apr 2018, 15:32, insgesamt 1-mal geändert.
Grund: Highlighter hinzugefügt

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Insert into funktioniert nicht

Beitrag von Michl »

Habe jetzt nicht alles detailiert gelesen, aber schreibst du die Daten dann auch weg?

Z.B. so:

Code: Alles auswählen

...
     FrmEQStamm.SQLQuery1.ExecSQL;
     FrmEQStamm.SQLQuery1.Commit// <---
     //Bestätigungsnachricht bei Eintrag
...

Das geht auch einmalig zusammengefasst bei einem OK-Button-Klick oder Programmende zu machen, z.B.:

Code: Alles auswählen

procedure TForm1.FormClose(Sender: TObject;
  var CloseAction: TCloseAction);
begin
  if SQLQuery1.ChangeCount > 0 then
    SQLQuery1.ApplyUpdates; // notwendig, wenn du mit den TSQLQuery Methoden arbeitest
  SQLTransaction1.Commit;
end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Vielen Dank, es funktioniert endlich mit dem zweiten Vorschlag

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Insert into funktioniert nicht

Beitrag von m.fuchs »

Kleiner Hinweis noch: das Zusammenstückeln der SQL-Statements mit einfacher String-Verknüpfung ist sehr schlechter Stil und eine potenzielle Sicherheitslücke.
Schau dir mal Parameterized Queries an.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Danke für die Info, die Daten werden nun per Parametern übergeben.

Code: Alles auswählen

procedure TFrmEQStamm.Button1Click(Sender: TObject);
 
begin
     //Datenbankverbindung aufbauen
     FrmConnectDB.connectDB;
 
     //Parameter anlegen
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'pcindex', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'geraet', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'hersteller', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'modell', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'seriennr', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'macadresse', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'invnr', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'datumeintrag', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'datumangeschafft', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'lieferscheinnr', ptInputOutput);
 
     //Werte den Parametern zuweisen
     FrmConnectDB.SQLQuery1.ParamByName('pcindex').AsString := '1';
     FrmConnectDB.SQLQuery1.ParamByName('geraet').AsString := ComboBox1.Text;
     FrmConnectDB.SQLQuery1.ParamByName('hersteller').AsString := ComboBox2.Text;
     FrmConnectDB.SQLQuery1.ParamByName('modell').AsString := Edit1.Text;
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := Edit2.Text;
     FrmConnectDB.SQLQuery1.ParamByName('macadresse').AsString := Edit3.Text;
     FrmConnectDB.SQLQuery1.ParamByName('invnr').AsString := Edit5.Text;
     FrmConnectDB.SQLQuery1.ParamByName('datumeintrag').AsString := FormatDateTime('yyyy.mm.dd', now);
     FrmConnectDB.SQLQuery1.ParamByName('datumangeschafft').AsString := Formatdatetime('yyyy.mm.dd', FrmEQStamm.DateTimePicker1.date);
     FrmConnectDB.SQLQuery1.ParamByName('lieferscheinnr').AsString := Edit6.Text;
 
     //Daten eintragen
     FrmConnectDB.SQLQuery1.SQL.Text:='INSERT INTO pc_geraete (pc_index,geraet,hersteller,modell,seriennummer,macadresse,inventarnummer,angelegt_am,anschaffungsdatum,lieferscheinnummer)'+
                                                      'VALUES (:pcindex,:geraet,:hersteller,:modell,:seriennr,:macadresse,:invnr,:datumeintrag,:datumangeschafft,:lieferscheinnr)';
     FrmConnectDB.SQLQuery1.ExecSQL;
 
     if FrmConnectDB.SQLQuery1.ChangeCount > 0 then
     FrmConnectDB.SQLQuery1.ApplyUpdates;
     FrmConnectDB.SQLTransaction1.Commit;
 
     //Bestätigungsnachricht bei Eintrag
     ShowMessage('(:geraet)');
 
     //Felder wieder leeren
     ClearAllFields;
end


Kann ich denn den Wert eines Parameters in einer showmessage ausgeben lassen?

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Insert into funktioniert nicht

Beitrag von m.fuchs »

Code: Alles auswählen

ShowMessage(FrmConnectDB.SQLQuery1.ParamByName('geraet').AsString);
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Vielen Dank nochmal für die Hilfe.

Jetzt möchte ich vor dem Eintrag prüfen, ob eine Seriennummer schon in der Datenbank hinterlegt ist. Den folgenden Code habe ich unter die Parameter und vor dem Dateneintrag geschrieben.

Code: Alles auswählen

 
     if FrmConnectDB.SQLQuery1.SQL.Text := 'Exists (SELECT * FROM pc_geraete where seriennummer = :seriennr)' then
     begin
          ShowMessage('Seriennummer schon vorhanden');
     end
 


Allerdings bekomme ich dann die Fehlermeldung "Error: Incompatible types: got "untyped" expected "Boolean"

Was ist bei meiner Abfrage falsch?

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Insert into funktioniert nicht

Beitrag von Michl »

Die Fehlermeldung ist etwas merkwürdig, rührt aber von dem ":" vor dem "=". Also so wird das Ganze kompiliert (wird aber nicht zum gewünschten Ergebnis führen):

Code: Alles auswählen

     if FrmConnectDB.SQLQuery1.SQL.Text = 'Exists (SELECT * FROM pc_geraete where seriennummer = :seriennr)' then
     begin
          ShowMessage('Seriennummer schon vorhanden');
     end

Wenn ich mich recht erinnere, ist Exists für Subabfragen bei einem Select gedacht. Ich würde das irgendwie so lösen (ungetestet):

Code: Alles auswählen

     FrmConnectDB.SQLQuery1.SQL.Text := 'SELECT * FROM pc_geraete where seriennummer = :seriennr;';
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := 'Seriennummer';
     FrmConnectDB.SQLQuery1.Open;
     if FrmConnectDB.SQLQuery1.RecordCount > 0 then
     begin
          ShowMessage('Seriennummer schon vorhanden');
     end;

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Insert into funktioniert nicht

Beitrag von Michl »

Achso, noch eine kleine Anmerkung. Wenn ein neues Problem auftaucht, ist es besser einen neuen Thread hier im Forum aufzumachen. Das Problem hat ja nichts mit dem Eingangsthema zu tun.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Vielen Dank für die schnelle Hilfe. Ich dachte es passt noch zum Thema weil es ja noch immer um das Insert geht bzw. die Prüfung vor dem Insert.

Ich bekomme mit dem Code bei jedem Eintrag nun die Meldung die Seriennummer sei vorhanden, obwohl diese in der Datenbank noch nicht vorhanden ist.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Insert into funktioniert nicht

Beitrag von Michl »

Hast du vorher die Query beendet? Also:

Code: Alles auswählen

     FrmConnectDB.SQLQuery1.SQL.Close// <- hier
     FrmConnectDB.SQLQuery1.SQL.Text := 'SELECT * FROM pc_geraete where seriennummer = :seriennr;';
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := 'Seriennummer';
...

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Dann bekomme ich die Fehlermeldung "Error: identifier idents no Member "Close""

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: Insert into funktioniert nicht

Beitrag von Socke »

Sayawa hat geschrieben:Dann bekomme ich die Fehlermeldung "Error: identifier idents no Member "Close""

Korrekt wäre:

Code: Alles auswählen

FrmConnectDB.SQLQuery1.Close; 
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

Das ganze funktioniert nun, ich habe es in eine neue Prozedur gepackt und rufe diese auf bevor gespeichert wird:

Code: Alles auswählen

 
procedure TFrmEQStamm.CheckSN;
 
begin
     //Datenbankverbindung aufbauen
     FrmConnectDB.connectDB;
     FrmConnectDB.SQLQuery1.Close;
     FrmConnectDB.SQLQuery1.SQL.Text := 'SELECT * FROM pc_geraete where seriennummer = :seriennr;';
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := Edit2.Text;
     FrmConnectDB.SQLQuery1.Open;
     if FrmConnectDB.SQLQuery1.RecordCount > 0 then
     begin
          ShowMessage('Seriennummer schon vorhanden');
          exit;
     end;
 
end;
 


Allerdings trägt er die Daten trotzdem ein, ich möchte aber, dass diese Fehlermeldung den Speichervorgang unterbricht. Darum habe ich das exit; nach Showmessage eingefügt. Nur hat dies nicht die erwünschte Wirkung. Ich bekomme die Fehlermeldung das die SN vorhanden ist und dann wird das ganze abgespeichert.

Sayawa
Beiträge: 13
Registriert: Do 26. Apr 2018, 15:15
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit

Re: Insert into funktioniert nicht

Beitrag von Sayawa »

erledigt, ich habe die Prüfung wieder in die eigentliche Prozedur geschrieben und nun bricht es auch ab wenn die SN bereits vorhanden ist.

Das ganze sieht jetzt so aus

Code: Alles auswählen

 
 
procedure TFrmEQStamm.Button1Click(Sender: TObject);
 
var
   //Variablen deklarieren
   strGeraet    :string;
 
begin
     //Datenbankverbindung aufbauen
     FrmConnectDB.connectDB;
 
     //prüfen ob SN bereits vorhanden
     FrmConnectDB.SQLQuery1.Close;
     FrmConnectDB.SQLQuery1.SQL.Text := 'SELECT * FROM pc_geraete where seriennummer = :seriennr;';
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := Edit2.Text;
     FrmConnectDB.SQLQuery1.Open;
     if FrmConnectDB.SQLQuery1.RecordCount > 0 then
     begin
          ShowMessage('Seriennummer schon vorhanden');
          exit;
     end;
 
     //Parameter anlegen
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'pcindex', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'geraet', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'hersteller', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'modell', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'seriennr', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'macadresse', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'invnr', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'datumeintrag', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'datumangeschafft', ptInputOutput);
     FrmConnectDB.SQLQuery1.Params.CreateParam(ftString, 'lieferscheinnr', ptInputOutput);
 
     //Werte den Parametern zuweisen
     FrmConnectDB.SQLQuery1.ParamByName('pcindex').AsString := EdtPcIndex.Text;
     FrmConnectDB.SQLQuery1.ParamByName('geraet').AsString := ComboBox1.Text;
     FrmConnectDB.SQLQuery1.ParamByName('hersteller').AsString := ComboBox2.Text;
     FrmConnectDB.SQLQuery1.ParamByName('modell').AsString := Edit1.Text;
     FrmConnectDB.SQLQuery1.ParamByName('seriennr').AsString := Edit2.Text;
     FrmConnectDB.SQLQuery1.ParamByName('macadresse').AsString := Edit3.Text;
     FrmConnectDB.SQLQuery1.ParamByName('invnr').AsString := Edit5.Text;
     FrmConnectDB.SQLQuery1.ParamByName('datumeintrag').AsString := FormatDateTime('yyyy.mm.dd', now);
     FrmConnectDB.SQLQuery1.ParamByName('datumangeschafft').AsString := Formatdatetime('yyyy.mm.dd', FrmEQStamm.DateTimePicker1.date);
     FrmConnectDB.SQLQuery1.ParamByName('lieferscheinnr').AsString := Edit6.Text;
 
     //Daten eintragen
     FrmConnectDB.SQLQuery1.SQL.Text:='INSERT INTO pc_geraete (pc_index,geraet,hersteller,modell,seriennummer,macadresse,inventarnummer,angelegt_am,anschaffungsdatum,lieferscheinnummer)'+
                                                      'VALUES (:pcindex,:geraet,:hersteller,:modell,:seriennr,:macadresse,:invnr,:datumeintrag,:datumangeschafft,:lieferscheinnr)';
     FrmConnectDB.SQLQuery1.ExecSQL;
 
     if FrmConnectDB.SQLQuery1.ChangeCount > 0 then
     FrmConnectDB.SQLQuery1.ApplyUpdates;
     FrmConnectDB.SQLTransaction1.Commit;
 
     //Bestätigungsnachricht bei Eintrag
     strGeraet := FrmConnectDB.SQLQuery1.ParamByName('geraet').AsString;
     ShowMessage('Es wurden folgende Angaben gespeichert:' + #10#13 + strGeraet);
 
     ClearAllFields;  //Felder leeren
     CreateIndex;     //neue Indexnr. erstellen
end;             
 

Antworten