//using System.Data;
//using System.Data.SqlClient;
//using System.IO;
private void CSV_XML_nach_Datenbank(String dateiPfad, String ZielTabelle, SqlConnection con)
{
//knoxyz 14.11.2008
try
{
DateTime startzeit = System.DateTime.Now;
//stellt Vermittler zwischen DatenQuelle(sqlServer) und DatenZiel(DataSet/DataTable) dar
SqlDataAdapter da = new SqlDataAdapter();
//enthält Tabellen
DataSet ds = new DataSet();
SqlCommand cmd = new SqlCommand(); //der sqlCommand nimmt SQL-Befehle entgegen
cmd.Connection = con; //generell festlegen, für welche Datenbank er diese Befehle ausführen soll
//ggf Verbindung herstellen
if (con.State != ConnectionState.Open) con.Open();
String schemaPfad = Application.StartupPath + @"\Schema_" + ZielTabelle + ".xsd";
//(Optional) Per TableMapping können Tabellen einen Namen gegeben werden. Alte Einträge entfernen
da.TableMappings.Clear();
//Welche Datenbankt
cmd.CommandText = "SELECT * FROM " + ZielTabelle;
da.SelectCommand = cmd;
da.TableMappings.Add("Table", ZielTabelle);
ds.Clear();
if (File.Exists(schemaPfad) == false) //Fall keine Schemadatei vorhanden ist, jetzt eine erstellen
{ //sofern Änderungen an der Datenbank gemacht wurden, die Schema.xsd einfach löschen
da.Fill(ds); //Tabellen des DataAdapter in ein DataSet schreiben
da.FillSchema(ds, SchemaType.Source); //Schema(Aufbau) der SQL-Tabellen auch im DataSet übernehmen
ds.WriteXmlSchema(schemaPfad); //Schema lokal speichern
}
//ds.WriteXml(schemaPfad + ".xml");//Schema und Daten lokal speichern (BackUp)
//Ziel-SQL-Tabelle
// anders als hier, schicke ich die Daten erst an eine Temp-Tabelle, die den gleichen Aufbau wie die eigentliche Ziel-Tabelle hat,
// und frage per Exist-Befehl anhand verschiedener Kriterien ab, ob Datensätze evtl. in der Ziel-Tab bereits vorhanden sind.
DataTable dt = new DataTable("Artikelstamm");
//um zu überprüfen ob die CVS-Daten zur SQL-Tabelle passen, hier das Schema der Datenbank übergeben
dt.ReadXmlSchema(schemaPfad);
//festlegen wo die CSV zu finden ist, die wir an die Datenbank schicken wollen
//Wurde eine eine 'xml-Datei' ausgesucht..
if (dateiPfad.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
{
dt.ReadXml(dateiPfad);
}
else
{
if (//...oder CSV/Textdatei?
(dateiPfad.EndsWith(".csv", StringComparison.OrdinalIgnoreCase))
|| (dateiPfad.EndsWith(".txt", StringComparison.OrdinalIgnoreCase))
)
{
StreamReader DateiLeser = new StreamReader(dateiPfad, System.Text.Encoding.Default);
//Die nachfolgende Replace-Aufrufe entfernen Sonderzeichen, die mögliche Probleme verursachen könnten
//Spaltenüberschriften auslesen und ggf. Punkte mit Unterstrich ersetzen
String Zeileninhalt = DateiLeser.ReadLine().Replace(".", "_").Replace("\t", ";");
DateiLeser.ReadLine(); //Leerzeile falls Daten erst in 3ter Zeile beginnen
char trennzeichen = ';';
//Der Inhalt der CSV-Datei wird Zeile für Zeile ausgelesen und in eine DataTable geschrieben
while (DateiLeser.EndOfStream == false)
{
Zeileninhalt = DateiLeser.ReadLine().Replace("'", "").Replace(";", "").Replace("=", "").Replace("\"", "");
Zeileninhalt = Zeileninhalt.Replace("\t", ";").Substring(0, Zeileninhalt.Length - 1);
//Zeileninhalt = Zeileninhalt.Replace("\t", ";"); //je nach CSV-Aufbau, diese oder Zeile darüber benutzen
//Inhalt einer Zeilen in Teilstrings zerlegen.
String[] csvZeilenInhalt = Zeileninhalt.Split(trennzeichen);
dt.Rows.Add(csvZeilenInhalt);
}
DateiLeser.Close();
}
else { MessageBox.Show("ungültige Datei ausgesucht", "falscher Dateityp"); }
}
if (dt.Rows.Count > 0) //wurden Daten aus der Quelldatei in DataTable kopiert?
{
//Jetzt liegt der Inhalt der CSV-Datei, auf Datentypen geprüft und mit Schema,
// im DataTable und kann in einem Rutsch (als Objekt) an den Datenbank-Server geschickt werden :-)
SqlBulkCopy bcopy = new SqlBulkCopy(con);
bcopy.DestinationTableName = ZielTabelle;
bcopy.WriteToServer(dt);
//dt.WriteXml(dateiPfad + ".xml"); //csv als xml speichern
String dauer = new DateTime(System.DateTime.Now.Ticks - startzeit.Ticks).ToString("mm 'Minuten und' ss 'Sekunden'");
MessageBox.Show(dt.Rows.Count + " Zeilen wurden in " + dauer + " verarbeitet :-)",
"Import war erfolgreich :-)");
dt.Clear();
//try
//{
//(optional) Log-Datei der Datenbank verkleinern
//cmd.CommandText = "DBCC SHRINKDATABASE(N'" + con.Database + "' )";
//cmd.ExecuteNonQuery();
//}
//catch (Exception e) { MessageBox.Show(e.Message); }
}
}
catch (Exception importFehler)
{
MessageBox.Show(importFehler.Message, "Import-Fehler");
}
}
//Hier folgt ein Beispiel wie die Methode aufgerufen werden könnte
private void BeispielZumAufrufDerImportMethode_Click(object sender, EventArgs e)
{ //Vorbereitung
String zielTabelle = "Artikelstamm";
String dateiPfad = String.Empty;
OpenFileDialog dateiAuswaehlen = new OpenFileDialog();
dateiAuswaehlen.Filter = "csv-Datei (*.txt)|*.txt"
+ "|xml-Datei (*.xml)|*.xml"
+ "|alle Dateien (*.*)|*.*";
dateiAuswaehlen.Title = zielTabelle;
if (dateiAuswaehlen.ShowDialog() == DialogResult.OK) dateiPfad = dateiAuswaehlen.FileName;
//Verbindungsaufbau definieren
SqlConnectionStringBuilder conBuilder = new SqlConnectionStringBuilder();
conBuilder.DataSource = "(local)"; //kann auch eine IP oder Name sein, dann ohne Klammern
conBuilder.InitialCatalog = "knoxyz";
conBuilder.ConnectTimeout = 10;
conBuilder.IntegratedSecurity = true; //oder User & Password
//conBuilder.UserID = "knoxyz";
//conBuilder.Password = "xyz";
SqlConnection con = new SqlConnection(conBuilder.ConnectionString);
//Prüfen ob Parameter Werte haben, falls nicht kein Aufruf
if ((dateiPfad != String.Empty) && (zielTabelle.Trim() != "") && (con.ConnectionString != ""))
CSV_XML_nach_Datenbank(dateiPfad, zielTabelle, con);
else MessageBox.Show("ParameterWerte für DB-Import stimmen nicht");
}