Aufgabenstellung
Es wird eine perfomante (ohne Cursor-Iterationen) Möglichkeit gesucht um Textdateien per C#.NET in den Microsoft SQL Server zu importieren.
Ansatz
C# bietet eine Klassenbibliothek mit den Klassen SqlBulkCopy und SqlBulkCopyOptions, die bereits im SAP Stammdaten Importer Tool vorgestellt wurde, und dessen Quellcode im unteren Abschnitt des Artikel als Visual Studio 2005 Projekt zum download angeboten wird. Dieses Tool ermöglicht das einlesen von SE16-Downloaddateien mit ein paar Millionen Datensätzen in weniger als 2 Sekunden. Bei der herkömmlichen Methode, einer Cursor-Iteration, wird je INSERT-Statement ein Datenbankaufruf/Netzwerkzugriff durchgeführt. Dies ist nur nicht mehr notwendig.
Lösung
DataTable füllen
...
DataTable dataTable = new DataTable();
...
// Spaltenüberschriften zum Table hinzufügen (in einer Schleife befüllbar)
for (/*Schleife um die Spaltennamen einzulesen*/)
{
// Die Anzahl der Columns muss = objects array sein
dataTable.Columns.Add("SPALTENNAME");
}
...
// Definition des Zeilenarrays
ArrayList objects = new ArrayList();
...
while(/*Schleife um zeilenweise über Datei zu iterieren*/)
{
...
for (/*Schleife um über Zellen der Zeile zu iterieren*/)
{
...
objects.Add(aktuellesZellenElementString);
...
}
...
// Hinzufügen des Datenelements, das die Zeilendaten hat
dataTable.Rows.Add(objects.ToArray());
}
...
DataTable in den MS SQL Server importieren
private void WriteToDatabase()
{
// get your connection string
string connString = msSqlServerString;
// connect to SQL
using (SqlConnection connection = new SqlConnection(connString))
{
// make sure to enable triggers
// more on triggers in next post
SqlBulkCopy bulkCopy = new SqlBulkCopy
(
connection,
SqlBulkCopyOptions.TableLock |
SqlBulkCopyOptions.FireTriggers |
SqlBulkCopyOptions.UseInternalTransaction,
null
);
// set the destination table name
bulkCopy.DestinationTableName = txtImportTable.Text;
connection.Open();
// write the data in the "dataTable"
try
{
bulkCopy.WriteToServer(dataTable);
}
catch (Exception e)
{
MessageBox.Show("Es ist ein Fehler aufgetreten. "+
"Stellen Sie sicher dass der Timeout im SQL Server "+
"auf unendlich steht und AutoClose für die Verbindung "+
"nicht aktiviert wurde. " + e.Message, "Fehler!");
}
connection.Close();
}
// reset
this.dataTable.Clear();
}
Ein komplettes Beispiel lässt sich hier downloaden:
Quellcode SAP Stammdaten Importer (VS 2005 Projekt)