![]() |
Datenbank: mySQL • Version: 5 • Zugriff über: MySQL Workbench
Problem Auslesen von MySQL und Ausgabe in ListViews
Moin moin,
ich habe ein Problem mit einer MySQL Datenbank in der Verbindung mit der Ausgabe in eine ListView. Ich suche schon den ganzen Tag nach hilfreichen Threads im Internet aber mir fallen keine passenden Stichwörter ein. Deshalb versuche ich es jetzt mal so. Kurze Erklärung was passieren soll: Ich habe eine Datenbankoberfläche programmiert, die diverse Editfelder, Buttons und auch 3 Listviews enthält. ListView1 enthält Artikel mit Preisen etc (Artikelstamm; Name: "barcodes"), ListView2 enthält einige, ausgewählte Einträge der 1. ListView (wie ein digitaler Kühlschrank; Name: "inhouse") und ListView 3 soll später ein Einkaufszettel werden, auf den man auch Einträge aus dem Artikelstamm hinzufügen kann usw (Name: "ekz"). Aber da bin ich noch nicht. Datenbanktechnisch ist das ganze über eine MySQL Datenbank mit derzeit 3 Tabellen gelöst. So nun zu meinem Problem: Bei Programmstart (später auch dynamischer) soll das Programm den Inhalt aller drei Tabellen in die jeweiligen ListViews schreiben. Mit der ListView1, also der Stammdatenbank, geht das auch wunderbar. Gibt mir alle Einträge aus. Sobald ich aber die Statements für ListView2 hinzufüge, schmeisst er mir mein Programm komplett durcheinander bis hin zur Startverweigerung. In mySQL kommen die Daten aber an. Es geht nur um Übertragen in die ListView. Ich wette, es ist eigentlich ganz einfach aber manchmal verbeisst man sich da so und findet seinen Fehler nicht. Da wäre ich für eure Hilfe sehr dankbar. Hier die betreffenden Zeilen:
Delphi-Quellcode:
Ich bin noch ziemlicher Anfänger und bin daher für jeden konstruktiven Tipp dankbar. Ich vermute den Fehler in der Art wie ich den Query angehe.
/bei Programmstart auslesen der Datenbank "barcodes"
SQLQuery1.SQL.Clear; SQLQuery1.Params.Clear; SQLQuery1.SQL.Text:= 'SELECT ID,Produktname,Hersteller,Inhalt,Lieferant,Preis,Barcode,Kommentar FROM barcodes'; SQLQuery1.Open; //schreiben der Daten aus der Datenbak "barcodes" in die Listview while not SQLQuery1.Eof do begin item:=mainFrm.ListView1.Items.Add; item.Caption:= SQLQuery1.FieldByName('ID').AsString; item.SubItems.Add(SQLQuery1.FieldByName('Produktname').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Hersteller').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Inhalt').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Lieferant').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Preis').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Barcode').AsString); item.SubItems.Add(SQLQuery1.FieldByName('Kommentar').AsString); SQLQuery1.Next; SQLQuery1.Close; end; //bei Programmstart auslesen der Datenbank "inhouse" SQLQuery2.SQL.Clear; SQLQuery2.Params.Clear; SQLQuery2.SQL.Text:= 'SELECT IDIH,ProduktnameIH,HerstellerIH,istIH,sollIH,MHDIH,BarcodeIH,KommentarIH FROM inhouse'; SQLQuery2.Open; //schreiben der Daten aus der Datenbank "inhouse" in die Listview while not SQLQuery2.Eof do item2:=mainFrm.ListView2.Items.Add; item2.Caption:= SQLQuery2.FieldByName('IDIH').AsString; item2.SubItems.Add(SQLQuery2.FieldByName('ProduktnameIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('HerstellerIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('istIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('sollIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('MHDIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('BarcodeIH').AsString); item2.SubItems.Add(SQLQuery2.FieldByName('KommentarIH').AsString); SQLQuery2.Next; SQLQuery2.Close; Vielen Dank. LG Vienesko:) |
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Hmm..
Zitat:
Fehlt da nach
Delphi-Quellcode:
nicht ein 'begin..end'
while not SQLQuery2.Eof do
|
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Ja, in der 2ten Schleife fehlt das begin/end + das SQLQuery.Close muss aus der Schleife raus:
while not SQLQuery1.Eof do begin item:=mainFrm.ListView1.Items.Add; item.Caption:= SQLQuery1.FieldByName('ID').AsString; item.SubItems.Add(SQLQuery1.FieldByName('Produktna me').AsString); ... SQLQuery1.Next; end; SQLQuery1.Close; |
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Außerdem würde ich mir eine Hilfsroutine schreiben (nennen wir sie DisplayData), der man ein TDataset und eine TListView-Instanz übergibt. Innerhalb dieser Routine werden dann zunächst alle Spalten und Zeilen der ListView gelöscht. Dann liest man die Feldnamen des Datasets aus und erzeugt daraus die Spalten neu. Anschließend geht man das Dataset durch und erzeugt wie gehabt je Datensatz eine neue Zeile und befüllt sie. Dadurch ist man flexibler und hat diese ganze Logik an zentraler Stelle.
|
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Und es wäre sinnvoll, vor dem Lesen der Daten die Listviews zu leeren.
Gruß K-H |
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
:-) Es wäre sinnvoll, den Zugriff auf die Daten (=SQL) vom UI (=ListView) zu trennen.
|
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Das ist immer sinnvoll. Die Frage ist nur, wie weit man (gerade als Anfänger) dabei gehen will. Wenn ich seit 3 Wochen programmiere, werde ich mich durch Begriffe wie Dependency Injection eher abgeschreckt fühlen.
|
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Zitat:
|
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Erstmal vielen Dank für die vielen und vor allem hilfreichen Antworten.
Natürlich war es das vergessene "begin...end" und der Query.close innerhalb der Schleife. Ich weiß nicht, warum mir das selbst nicht aufgefallen ist. Aber irgendwann ist man wahrscheinlich einfach blind dafür...:roll: Das Andere müsst ihr mir aber erklären. Ist mir der Hilfsroute gemeint, sich einemal eine Procedure zu schreiben, in der das abläuft und diese dann zu gegebener Zeit aufzurufen? Und warum macht es sinn, die ListView zu leeren? Warum Listview/SQL trennen? Ich möchte ja was lernen und mich verbessern:) Danke! |
AW: Problem Auslesen von MySQL und Ausgabe in ListViews
Moin...:P
Zitat:
Wie weit du dich darauf einläßt und die Tipps umsetzt, ist dir überlassen. Als Anfänger hab ich mich auch nicht darum gekümmert...:oops: Aber auch als Anfänger sollte man es schon wenigstens gehört haben. Learning by doing ohne Hilfe ist nicht schlecht aber sehr zeitaufwendig. Besser ist, die erhaltenen Tipps selbst auszuprobieren und daraus zu lernen. Ich wünschte, daß hätte ich damals auch gehabt... :cry: Dafür ist das Forum da...:thumb: Der Reihenfolge nach: 1: Progammierprinzipien: (die Wichtigsten) DRY: ![]() * Dopplung von Code durch auslagern in Methoden vermeiden * Bestehenden Code verwenden und danach suchen KISS: ![]() * Wenn es mehrere Erklärungen für einen bestimmten Sachverhalt gibt, dann ist diejenige Erklärung zu bevorzugen, die am einfachsten ist, also mit den wenigsten Annahmen und Variablen auskommt. Allgemein: CamelCase: ![]() vernünftige Namen: Auch wenn es am Anfang lästig ist, man hat ja andere Probleme, ist es besser das man sich gleich daran gewöhnt. In 2 Monaten weist du nicht mehr was ListView1 ist. :zwinker: Denglisch vermeiden: Auch wenn wir Deutsch sind... in der Programmierei ist Englisch die bevorzugte Sprache. Damit hat man auch die Probleme mit Umlauten vom Tisch. Wenn man dann in einem Team arbeitet muß man sich nicht umgewöhnen. 8-) Styleguide: ![]() WITH vermeiden: :warn: Fast vergessen. Mit WITH nimmst du dir alle Möglichkeiten den Code, bzw. die Variablen, zu debuggen. Erst Recht als Anfänger will man doch wissen was in der Komponente (Property) los ist... :zwinker: 2: Werkzeuge allgemein: Programmieren geht mit der Benutzung der zur Verfügung stehenden Werkzeuge los. Der CnPack ist einer davon. Mit den bunten Strichen im Quelltext wäre dir das: Zitat:
Codeformatter: Das Wichtigste ist ein gut formatierter Code. (kommt auch im Forum nicht schlecht...8-)) Mit einem Tastendruck (CnPack) ist alles "toll" ausgerichtet...:thumb: Was ist besser? das
Delphi-Quellcode:
oder das?
while not SQLQuery1.Eof do
begin item:=mainFrm.ListView1.Items.Add; item.Caption:= SQLQuery1.FieldByName('ID').AsString; item.SubItems.Add(SQLQuery1.FieldByName('Produktna me').AsString); ... SQLQuery1.Next; end; SQLQuery1.Close;
Delphi-Quellcode:
3.
while not SQLQuery1.Eof do
begin Item := mainFrm.ListView1.Items.Add; Item.Caption := SQLQuery1.FieldByName('ID').AsString; Item.SubItems.Add(SQLQuery1.FieldByName('Produktname').AsString); ... SQLQuery1.Next; end; SQLQuery1.Close; Zitat:
4. Zitat:
allgemeiner Programmaufbau (Schicht Model): ![]() ...ist für den Anfang zu kompliziert. Aber das ist das was damit gemeint wurde. Für den Anfang kannst du dich an folgende Tipps halten: * GUI<->Logik<->Datenbank Für jeden Part gibt es eine Unit oder DataModule. * Definition der Datenablage...in der Regel die Unit mit der Logik. Die GUI holt sich direkt, oder über Events, die Daten dort ab. Das hat den Vorteil das du die GUI austauschen/verändern kannst ohne die Datenstruktur anzufassen. * visuelle Controls niemals als Datenablage benutzen. Die Daten immer in der Logik vorhalten (Variable, DataSet etc.). * SQL gehören nicht auf die Form oder in die auf die Form gepappte Query, sondern in eine seperate Unit oder Datenmodul. (erleichert den Austausch des DBMS) * strikte Trennung Ablage der Prozeduren... alles was mit der GUI zu tun hat gehört in die Form, Berechnungen etc. in die Logik. Zitat:
Zitat:
5. Zitat:
6. Datenbank:
Delphi-Quellcode:
Auch für die Datenbank gilt: "Denglisch vermeiden" und Präfixe für Felder- und Tabellennamen wegen der reservierten Worte der Datenbank. (F_xxx, T_xxx ...oder so )
item.Caption:= SQLQuery1.FieldByName('ID').AsString; // sollte in der Datenbank ein Integer und Primary Key sein!
... item2.Caption:= SQLQuery2.FieldByName('IDIH').AsString; // sollte in der Datenbank ein Integer und Primary Key sein! // Das ID Feld sollte in jeder Tabelle den gleichen Namen haben... :-) Verwechslungsgefahr... 7. Verbesserungen:
Delphi-Quellcode:
Frage:
/bei Programmstart auslesen der Datenbank "barcodes"
// verfünftige Namen // wenn die Colums im OI definiert wurden. Mit lvBarcodes.Clear müssen auch die Colums definiert werden. Das ist das was DeddyH mit allgemein gemeint hatte. lvBarcodes.Items.Clear; //QueryBarcodes.SQL.Clear; // nicht notwendig...passiert mit Zuweisung von "SQL.Text" automatisch //QueryBarcodes.Params.Clear; // nicht notwendig...passiert mit Zuweisung von "SQL.Text" automatisch QueryBarcodes.SQL.Text := 'SELECT ID,Produktname,Hersteller,Inhalt,Lieferant,Preis,Barcode,Kommentar FROM barcodes'; //Leerzeichen QueryBarcodes.Open; //schreiben der Daten aus der Datenbak "barcodes" in die Listview while not QueryBarcodes.Eof do begin Item := mainFrm.lvBarcodes.Items.Add; // Name Item.Caption := QueryBarcodes.FieldByName('ID').AsString; Item.SubItems.Add(QueryBarcodes.FieldByName('Produktname').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Hersteller').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Inhalt').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Lieferant').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Preis').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Barcode').AsString); Item.SubItems.Add(QueryBarcodes.FieldByName('Kommentar').AsString); QueryBarcodes.Next; end; // außerhalb der Schleife. Imho ist Close nicht notwendig. Mit Zuweisung von "SQL.Text" und dem Open wird Close automatisch augeführt. QueryBarcodes.Close; Ohne dir auf die Füße treten zu wollen...Wie kommt man als Anfänger an eine XE7 Enterprise? :gruebel: Dann viel Spaß... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:36 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