Laden...

Mit zwei Readern gleichzeitg aus MySQL-DB lesen

Erstellt von KevinHappy vor 9 Jahren Letzter Beitrag vor 9 Jahren 1.993 Views
K
KevinHappy Themenstarter:in
41 Beiträge seit 2015
vor 9 Jahren
Mit zwei Readern gleichzeitg aus MySQL-DB lesen

Hallo,

ich habe 2 Datenbank Tabellen export und export_ean. export beinhaltet Produkdaten und export_ean die EAN's, da ein Artikel mehrere EAN's (vom Lieferant, Hersteller, etc..) haben kann.

public void insertDataToProductsXml()
        {
            MySqlCommand command = mysqlConnection.CreateCommand();
            MySqlDataReader Reader;
            string sOrderNr = "";
            try
            {
                if (this.Connect() == true)
                {
                    XmlWriterSettings settings = new XmlWriterSettings();
                    settings.Indent = true;
                    settings.IndentChars = "  "; // 2 Leerzeichen
                    XmlWriter writer = XmlWriter.Create(@"C:\\Pfad\\zur\\Datei\\products_test.xml", settings);
                    writer.WriteStartDocument();
                    // Start-Tag von 'Products'
                    writer.WriteStartElement("Products");

                    command.CommandText = "SELECT * FROM article_list_export";
                    Reader = command.ExecuteReader();
                    while (Reader.Read())
                    {

                        sOrderNr = Reader.GetValue(1).ToString();

                        //retVendorNumber.Add(Reader.GetValue(0).ToString());
                        // Start-Tag von 'Product'
                        writer.WriteStartElement("Product");

                            writer.WriteElementString("ProductName", Reader.GetValue(6).ToString());
                            // Element mit Attributen
                            writer.WriteStartElement("ProductDetailDescription1");
                            writer.WriteCData(Reader.GetValue(7).ToString());
                            writer.WriteEndElement();

                            writer.WriteStartElement("ProductDetailDescription2");
                            writer.WriteCData(Reader.GetValue(8).ToString());
                            writer.WriteEndElement();


                            writer.WriteStartElement("Pricelists");
                            writer.WriteStartElement("Pricelist");
                            writer.WriteElementString("PriceGross", Reader.GetValue(5).ToString());
                            writer.WriteEndElement();
                            writer.WriteEndElement();


                            writer.WriteStartElement("Images");
                            writer.WriteStartElement("Image");
                            writer.WriteElementString("ImagePath", Reader.GetValue(10).ToString());
                            writer.WriteEndElement();
                            writer.WriteEndElement();

                            writer.WriteStartElement("EANs");

                            foreach (string ean in getEanExport(sOrderNr))
                            {
                                writer.WriteStartElement("EAN");
                                writer.WriteString(ean);
                                writer.WriteEndElement();
                            }

                            writer.WriteEndElement();

                        // End-Tag von 'Product'
                        writer.WriteEndElement();
                    }
                    // End-Tag von 'Products'
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Close();
                    this.Disconnect();
                }
            }
            catch (MySqlException e)
            {
                Console.WriteLine("Fehler: " + e.Message + " | Nummer: " + e.Number.ToString());
                this.Disconnect();
            }
            catch (Exception e)
            {
                Console.WriteLine("Fehler: " + e.Message);
                this.Disconnect();
            }
        }
public List<string> getEanExport(string ordernr)
        {
            List<string> retEan = new List<string>();
            try
            {
                MySqlCommand command = mysqlConnection.CreateCommand();
                command.CommandText = "SELECT ean FROM article_list_export_ean WHERE article_ordernr = " + ordernr;
                MySqlDataReader ReaderEan;
                ReaderEan = command.ExecuteReader();
                while (ReaderEan.Read())
                {
                    retEan.Add(ReaderEan.GetValue(0).ToString());
                }
                ReaderEan.Close();
                
            }
            catch (MySqlException e)
            {
                Console.WriteLine("Fehler: " + e.Message + " | Nummer: " + e.Number.ToString());
            }
            catch (Exception e)
            {
                Console.WriteLine("Fehler: " + e.Message);
            }
            return retEan;
        }

Mein Problem ist, dass ich keine 2 MySqlDataReader instanzen gleichzeitig verwenden kann. Gibt es für MySQL auch sowas wie MARS? Wie löst man das Problem am besten?

Stehe gerade voll auf dem Schlauch. 8o

--
Vielen Dank

LG
Kevin

2.760 Beiträge seit 2006
vor 9 Jahren

Servus KevinHappy,

Dein Fall schaut aus als on Du in Deiner SQL-Abfrage eigentlich nur einen JOIN benötigen würdest:


SELECT * FROM article_list_export
   JOIN article_list_export_ean ON article_list_export_ean.article_ordernr = article_list_export.ordernr

Damit kannst Du die verschachtelte Abfrage innerhalb der while-Schleife weglassen und musst auch nicht so viele Anfragen an den Server stellen.
Das dürfte unterm Strich ein Vielfaches schneller sein als Dein jetziger Code.

Noch ein weiterer Tipp: Benutze für Datenbankresourcen (Connection, Command etc.) immer die using-Anweisung anstatt manuell Close und Dispose aufzurufen. Die Using-Anweisung ruft auch im Falle einer Exception immer Dispose auf so dass Du die Try-Catch-Blöcke in deinem Code weglassen kannst.

Generell gilt, dass man Exceptions nur dann fängt, wenn man sie an der Stelle auch sinnvoll behandeln kann. In Deinem Fall würden einfach Daten weggelassen werden falls es zu einem Fehler kommt was ziemlich unvorhersehbares Verhalten hervorrufen kann.

Logging kannst Du auch weiter "oben" in Deinem Code einbauen. Wenn z.B. die MySqlException nicht gefangen wird, landet sie früher oder später in der Main-Methode Deines Programms. Dort kannst Du sie immer noch Loggen.

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo KevinHappy,

hol dir doch mit einem Join alles auf einmal. Dann sparst du dir zwei Queries.

Nebenbei: Schreibe Methoden gross.

Beachte bitte [Artikelserie] SQL: Parameter von Befehlen und auch [Artikel] Drei-Schichten-Architektur , dazu [Tipp] Anfängerfehler == true / == false

Gruss

Coffeebean

Edit: Zu langsam 😃

K
KevinHappy Themenstarter:in
41 Beiträge seit 2015
vor 9 Jahren

Das mit JOIN hatte ich auch in betracht gezogen.
Aber ich bekomme dann die Datensätze so oft angezeigt, wie EANs vorhanden sind.

Hast du da auch einen Tipp für mich?

Spontan hätte ich die Bestellnummern alle in eine List geschrieben und immer geschaut, ob die schon vorhanden ist. Sodas ich doppelte Einträge vemeide.

Ich schreibe die Artikel in eine XML, die wiederum vom ERP-System eingelesen wird. Und da wäre es sehr nervig, wenn auf einmal alles doppelt und dreifach vorhanden wäre.

--
Vielen Dank

LG
Kevin

T
314 Beiträge seit 2013
vor 9 Jahren

Wenn die Daten die du aus der EAN Tabelle abfragst nicht unterscheiden, kannst Du ein DISTINCT verwenden.

K
KevinHappy Themenstarter:in
41 Beiträge seit 2015
vor 9 Jahren

DISTINCT bringt nichts.

Da die EANs ja immer unterschiedlich sind, greift DISTINCT ja nicht. Ich hab ja alle Daten gleich bis auf die EANs.

--
Vielen Dank

LG
Kevin

R
228 Beiträge seit 2013
vor 9 Jahren

Warum sind alle Daten gleich, bis auf die EAN's ?

Normalerweise könntest du bei einem Join auch mehrere "Bedingungen" angeben.


Select *
From Tabbelle1
inner join Tabbelle2 on Tabbelle2.Spalte1 = Tabbelle1.Spalte1 and Tabbelle2.Spalte2 = Tabbelle1.Spalte2

Eigentlich solltest du so vernünftig selektieren können, was für Daten durch deinem Join zusammengefasst werden

T
314 Beiträge seit 2013
vor 9 Jahren

Dann mach halt eine Abfrage inkl. JOIN und lies die Daten so aus, dass sie in deine gewünschte Struktur passen.