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
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.
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 😃
Microsoft MVP // Me // Blog // GitHub // @Egghead // All my talks // Speakerdeck
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
Wenn die Daten die du aus der EAN Tabelle abfragst nicht unterscheiden, kannst Du ein DISTINCT verwenden.
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
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
Dann mach halt eine Abfrage inkl. JOIN und lies die Daten so aus, dass sie in deine gewünschte Struktur passen.