MySQL Datensätze einlesen [HILFE]

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

Hallo da bin ich auch schon wieder mit dem nächsten Problem. Gestern war ich ganz stolz das es endlich funktioniert und heute habe ich schon wieder Fragezeichen übern Kopf.

Es geht immer noch um meine Software Patientenerfassung. Ich habe jetzt auch wieder mehrere Tutorials gelesen und jedes macht es anders. (Viele Köche verderben den Brei)
Naja also Problem ist jetzt ich möchte meine MySQLTabelle beschreiben. Dazu geht eine neue Form auf wo alle Daten rein geschrieben werden. Wenn man dort auf Speichern klickt wird der Datensatz an die Form davor gegeben. Das ganze Passiert mit einem Button

Code: Alles auswählen

procedure TForm3.BitBtn1Click(Sender: TObject);
var
  nr:string;
begin
  nr:=enummer.text;
  Form2.SQLQuery1.Close;
  Form2.SQLQuery1.SQL.Clear;
  Form2.SQLQuery1.SQL.Text:= 'select * from Patientenerfassung';
  Form2.SQLQuery1.SQL.Text:= 'INSERT INTO patientenerfassung (Nummer) VALUES ('+ nr + ')';
  Form2.MySQLConnection1.Connected:= True;
  Form2.SQLTransaction1.Active:= True;
  Form2.SQLQuery1.Open;
 
end;


Meine Erklärung dazu (damit ich den Fehler nachher besser verstehe):
als erstes lese ich mein Edit aus und stecke den Text in eine Variable.
Dann schließe ich erst mal die Query weil ich ja nicht weiß ob die offen ist. Weil kann die ja nur bearbeiten wenn die zu ist.
Dann lösche ich die Einträge im Query weil ich ja nicht weiß was drinne liegt.
Dann wähle den Datensatz aus.
Danach schreibe ich in die Tabelle, dann wird der Kontakt hergestellt übertragen und eingefügt.

jetzt kommt aber immer ein Fehler das er die Datenbank nicht auswählen kann. Was ist Falsch?

p.s. macht es eigentlich Unterschiede zwischen ein Edit und einen DBEdit? Bzw bringt es Vorteile?

EDIT: Fehlermeldung ist Can't open a non select-statement
aber habe doch was selektiert???

knight
Beiträge: 802
Registriert: Mi 13. Sep 2006, 22:30

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von knight »

Wenn du zweimal eine Zuweisung an

Code: Alles auswählen

Form2.SQLQuery1.SQL.Text
vornimmst, dann wird mit der zweiten Zuweisung die erste überschrieben. In deinem Fall bleibt die Insert-Anweisung übrig. Um diese auszuführen müsstest du

Code: Alles auswählen

Form2.SQLQuery1.ExecSQL;
verwenden.

knight

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
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: MySQL Datensätze einlesen [HILFE]

Beitrag von af0815 »

Schon mal die Lazinfos Kapitel 3 & 8 angesehen ?

Kapitel 3 sind die Grundlagen für Datenbanken. Da werden die wichtigsten Befehle wie SELECT, INSERT, UPDATE und DELETE erklärt.
Kapitel 8 wird eine Datenbank Schritt für Schritt aufgebaut und mit Daten gefüllt. Die Beispiele kann man über Sourceforge sich auch herunterladen.

In Kapitel 8.1.3 wird das mit den Parametern erklärt.

Den Fragen nach, gehört zuerst ein Datenbank Tutorial durchgearbeitet, bevor es an eine reale Applikation geht. Kostet auch nicht soviel Zeit und die gewinnt man später bein Programmieren.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Michl »

Ich verändere mal deine Code, was du auch hättest weglassen können:

Code: Alles auswählen

...
  nr:=enummer.text;
//  Form2.SQLQuery1.Close;
//  Form2.SQLQuery1.SQL.Clear;
//  Form2.SQLQuery1.SQL.Text:= 'select * from Patientenerfassung';
  Form2.SQLQuery1.SQL.Text:= 'INSERT INTO patientenerfassung (Nummer) VALUES ('+ nr + ')';
Mit SomeQuery.SQL.Text := ... schließt du automatisch die Query und überschreibst immer den davor enthaltenen Text.

Warum machst du das?

Code: Alles auswählen

  Form2.MySQLConnection1.Connected:= True;
  Form2.SQLTransaction1.Active:= True;
Die Connection brauchst du in den meisten Fällen, solange du mit der Datenbank arbeitest nicht zu trennen und wieder zu verbinden (außer bei z.B. einen kompletten Update deiner Datenbank, aufheben einer Sperrung der Datenbank durch Privilegien der Connection, Änderung der Datenbankstruktur etc.).

Zum eigentlichen Problem der Meldung:

Code: Alles auswählen

  Form2.SQLQuery1.SQL.Text:= 'INSERT INTO patientenerfassung (Nummer) VALUES ('+ nr + ')';
...
  Form2.SQLQuery1.Open;
Die Query kann mit einer Insert Anweisung nicht geöffnet werden, mit einem Select schon:

Code: Alles auswählen

  Form2.SQLQuery1.SQL.Text:= 'select * from Patientenerfassung';
...
  Form2.SQLQuery1.Open;


Es gibt hauptsächlich zwei unterschiedliche Möglichkeiten Daten in die DatenbankTabelle zu schicken (in dem man die Methoden vom Query nutzt oder per SQL-Statement):

z.B. (http://wiki.freepascal.org/Lazarus_Database_Tutorial/de#Simple_MySQL_Demo_Using_the_TMySQL50Connection_Component).:

Code: Alles auswählen

procedure TForm1.btnNewClick(Sender: TObject);
begin
  query.Append;
  query.FieldValues['personid'] := edtPersonID.Text;
  query.FieldValues['surname'] := edtSurname.Text;
  query.FieldValues['dob'] := edtDOB.Text;
  query.Post
  query.ApplyUpdates; //to apply update
  //transaction.Commit; //line not needed
end;


oder (http://wiki.freepascal.org/Working_With_TSQLQuery#Insert_query_example)

Code: Alles auswählen

 sql_temp.sql.text := 'insert into PRODUCTS (ITEMNR,DESCRIPTION) values (:OURITEMNR,:OURDESCRIPTION)'
 ...
 sql_temp.Params.ParamByName('OURITEMNR').AsString := 'XXXX';
 sql_temp.Params.ParamByName('OURDESCRIPTION').AsString := 'description';
 sql_temp.ExecSQL;
 SQLTransaction1.Commit; //or possibly CommitRetaining, depending on how your application is set up


das SQL-Statement kann man auch per Connection aufrufen ([url]Query with Format function[/url]) :

Code: Alles auswählen

procedure InsertRecord
var
  aSQLText: string;
  aSQLCommand: string;
begin
  aSQLText:= 'INSERT INTO products(item_no, description) VALUES(%d, %s)';
  aSQLCommand:= Format(aSQLText, [strtoint(Edit1.Text), Edit2.Text]);
  aConnection.ExecuteDirect(aSQLCommand);
  aTransaction.Commit;
end;

Code: Alles auswählen

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

Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

danke erst mal alle... :)
af0815 das tutorial habe ich... finde es aber irgend wie ein bisschen unübersichtlich gemacht...

sonst Michl

Code: Alles auswählen

procedure TForm1.btnNewClick(Sender: TObject);
begin
  query.Append;
  query.FieldValues['personid'] := edtPersonID.Text;
  query.FieldValues['surname'] := edtSurname.Text;
  query.FieldValues['dob'] := edtDOB.Text;
  query.Post
  query.ApplyUpdates;
  transaction.Commit;
end;


hiermit geht es am besten... problem nur... erst mit transaction.commit schreibt er erst den datensatz auf den mysqlserver bzw in die tabelle und danach meldet er sich ab vom server(augenscheinlich)... gibt es bei dem transaction ein anderen befehl der sagt hochladen aber nicht danach abmelden?

weil wenn ich abspeichere geht er von form3 auf form2 zurück und dort ist ein dbgrid was die ganze zeit offen bleiben muss und alles anzeigen muss... wobei mein dbgrid nur die ersten beiden spalten anzeigt und in den restlichen (MEMO) anzeigt... obwohl die spalten bzw zeilen beschrieben sind

EDIT: ok beim grid problem ist mir aufgefallen an was es liegen könnte... es ist vermutlich der mysql server... weil wenn ich die spalte umstelle auf char im mysqlserver dann gibt mir die dbgrid die spalte wieder... aber sobald ich text mediumtext oder londtext auswähle dann gibt mir es die dbgrid nicht wieder :/ und bei mysql kann ich nur char oder text auswählen... was braucht delphi zum auslesen?

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von TBug »

Aphadias hat geschrieben:danke erst mal alle... :)
EDIT: ok beim grid problem ist mir aufgefallen an was es liegen könnte... es ist vermutlich der mysql server... weil wenn ich die spalte umstelle auf char im mysqlserver dann gibt mir die dbgrid die spalte wieder... aber sobald ich text mediumtext oder londtext auswähle dann gibt mir es die dbgrid nicht wieder :/ und bei mysql kann ich nur char oder text auswählen... was braucht delphi zum auslesen?

Das ist kein Problem des MySql-Servers, sondern gar kein Problem im eigentlichen Sinne.

Das DBGrid kann keine Felder mit Blob-Daten oder Memo-Daten (LongText, MediumText) direkt darstellen.

Dafür gibt es die Komponente DBMemo.


.

Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

na super... meine idee war es den datensatz in einer tabelle anzeigen zu lassen um alles übersichtlich zu sehen... dann wollte ich den datensatz aus der tabelle auswählen

EDIT: habe jetzt das gefunden

Code: Alles auswählen

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
  memowidth = 10; // 10 Zeichen
var
  s: string
begin
  with (Sender as TDBGrid) do begin
    if Column.Field.IsBlob then begin
      Canvas.FillRect(Rect);
      s := copy(Column.Field.AsString, 1, memowidth);
      Canvas.TextOut(Rect.Left+2, Rect.Top+2, s);
    end else begin
      DefaultDrawColumnCell(Rect, DataCol, Column, State);
    end;
  end;
end;


das geht... :)

aber habe mein eigentliches problem noch mit dem transaction.commit ;)

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von TBug »

Aphadias hat geschrieben:hiermit geht es am besten... problem nur... erst mit transaction.commit schreibt er erst den datensatz auf den mysqlserver bzw in die tabelle und danach meldet er sich ab vom server(augenscheinlich)...


Beschreibe einmal was Du siehst oder was passiert, wenn "er sich vom Server abmeldet".


.

Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

ich habe auf Form2 eine DBGrid. Sobald ich das Programm öffne (bzw Form2) wird die DB ausgelesen und die DBGrid zeigt mir eine grobe Übersicht an. Wenn ich jetzt neu erstellen gehe und Form3 damit auf mache und dort meine Daten eingebe und abspeichere dann wird der Befehl Speichern ja mit transaction.commit beendet und Form3 geschlossen und Form2 wieder angezeigt. Nur jetzt ist DBGrid nicht mehr gefüllt sondern leer. Das darf aber später nicht sein weil mit der DBGrid dann gleich weiter gearbeitet werden muss.

das sehe ich @TBug

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
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: MySQL Datensätze einlesen [HILFE]

Beitrag von af0815 »

Wenn du die Daten änderst, besonders in einem anderen Form, dann solltest du das Grid aktualisieren, denn es sollte die Änderung der Daten ja wiederspiegeln. Am einfachsten wenn du die Query erneut ausführst.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

TBug
Beiträge: 177
Registriert: Mi 2. Sep 2015, 11:09
OS, Lazarus, FPC: Lazaurus 2.2.4 FPC 3.2.2
CPU-Target: Windows 32/64bit

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von TBug »

Aphadias hat geschrieben:ich habe auf Form2 eine DBGrid. Sobald ich das Programm öffne (bzw Form2) wird die DB ausgelesen und die DBGrid zeigt mir eine grobe Übersicht an. Wenn ich jetzt neu erstellen gehe und Form3 damit auf mache und dort meine Daten eingebe und abspeichere dann wird der Befehl Speichern ja mit transaction.commit beendet und Form3 geschlossen und Form2 wieder angezeigt. Nur jetzt ist DBGrid nicht mehr gefüllt sondern leer. Das darf aber später nicht sein weil mit der DBGrid dann gleich weiter gearbeitet werden muss.


So wie ich das sehe benutzt Du für das Anzeigen der Daten im DBGrid der Form2 die gleiche Query wie für das Schreiben der Daten, welche Du in Form3 eingibst.

Dann ist es ja logisch, dass das Grid nichts mehr anzeigen kann, da ja nach dem Ausführen der Query mit einem "INSERT"-, "UPDATE"- oder "DELETE"-Statement keine Datensätze mehr in der Query enthalten sein können.

Wie af0815 bereits geschrieben hat musst Du dann natürlich wieder ein SQL-Statement (z.B "SELECT * FROM tabelle") ausführen, damit die Query wieder mit Daten aus der Tabelle gefüllt wird.


.

Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

Ja habe ich auch schon so umgesetzt. Hatte gedacht geht auch einfacher. Aber jetzt geht es danke euch ;)

Aphadias
Beiträge: 124
Registriert: Mi 28. Okt 2015, 18:28

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aphadias »

Moin,

ich habe ein Problem festgestellt. Jeder Datensatz soll ja einmalig sein. Wenn ich jetzt ein öffne und dann wieder speichere... dann legt er ja den immer neu an. Der soll aber den alten Text überschreiben.

Aktuell speichere ich mit dem Code:

Code: Alles auswählen

Form2.SQLQuery1.Append;
Form2.SQLQuery1.FieldValues['Nummer']:=enummer.text;
Form2.SQLQuery1.FieldValues['ZAB']:=ezab.text;
Form2.SQLQuery1.FieldValues['Name']:=ename.text;
Form2.SQLQuery1.FieldValues['Vorname']:=evorname.text;
Form2.SQLQuery1.FieldValues['Geb-Datum']:=egeb.text;
...
...
...
Form2.SQLQuery1.Post;
Form2.SQLQuery1.ApplyUpdates;
Form2.SQLTransaction1.Commit;


ich wollte es erst mit einer If schleife lösen. Problem ist nur. Egal ob die If-schleife erkennt ob es das gibt oder nicht, der Befehl am Ende sagt ja eh nur einfach speichern. Gibt es nen Befehl der sagt wenn es das gibt dann überschreibe das ganze?
Oder muss ich ein extra Button machen mit dem ich überschreibe?

Aliobaba
Lazarusforum e. V.
Beiträge: 496
Registriert: Di 1. Mai 2012, 09:11

Re: MySQL Datensätze einlesen [HILFE]

Beitrag von Aliobaba »

UPDATE?
"MyMemoryDB" ( https://www.heise.de/download/product/mymemorydb-89626 )

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6208
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: MySQL Datensätze einlesen [HILFE]

Beitrag von af0815 »

Query.append legt immer einen neuen Datensatz an. PUNKT.

Öffne die Query ohne append. Navigiere zu den Datensatz, den du ändern willst. Ändere die Date. Query.post und query.applyupdates, dann ist das ganz in der DB.

Wenn die query nicht kompliziert ist (keine joins) und der PK der Query bekannt ist, erzeugt die Query selbstständig die richtigen Statemnts für insert, update und delete.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten