Für das Einfügen und Aktualisieren großer Datenmengen ist ADO.NET tatsächlich nicht so gut wie JDBC und verfügt über ein einheitliches Modell für Stapeloperationen.
PreparedStatement ps = conn.prepareStatement("arg1,args2...." einfügen oder aktualisieren);
dann kannst du
for(int i=0;i<1000000000000000;i++){
ps.setXXX(realArg);
.....
ps.addBatch();
if(i%500==0){ //Angenommen, fünfhundert Artikel werden einmal übermittelt
ps.executeBatch();
//Parameter-Batch löschen
}
}
ps.executeBatch();
Eine solche Operation bringt nicht nur eine extrem hohe Leistung, sondern ist auch sehr praktisch. Um eine solche Funktion zu implementieren, sollten in ADO.NET normalerweise die Addbat- und CommitBat-APIs direkt in der Befehlsschnittstelle oder der DataAdapter-Schnittstelle bereitgestellt werden, jedoch in ADO. NET ist jedoch nicht so einfach zu implementieren, sondern erfordert von den Entwicklern komplexe Umgehungslösungen.
Bei einer großen Anzahl von Einfügevorgängen können Sie eine leere DataTable verwenden, um die einzufügenden Zeilen hinzuzufügen, und die Tabelle dann nach einer bestimmten Anzahl von Übermittlungen leeren.
Die Umsetzung ist nicht allzu kompliziert:
DateTime begin = DateTime.Now;
string ConnectionString = ...;
using(SqlConnection conn = new SqlConnection(connectionString))...{
conn.Open();
SqlDataAdapter sd = new SqlDataAdapter();
sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest", conn);
sd.InsertCommand = new SqlCommand("insert into CurrentTest (devid,data_time,data_value) "
+ „values (@devid,@data_time,@data_value);“, conn);
sd.InsertCommand.Parameters.Add("@devid", SqlDbType.Char, 18, "devid");
sd.InsertCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.InsertCommand.Parameters.Add("@data_value", SqlDbType.Int, 8, "data_value");
sd.InsertCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
DataSet dataset = new DataSet();
sd.Fill(dataset);
Zufällig r = new Random(1000);
for (int i = 0; i < 100000; i++) ...{
object[] row = ...{"DEVID"+i,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),r.Next(1,1000) };
dataset.Tables[0].Rows.Add(row);
if (i % 300 == 0) ...{
sd.Update(dataset.Tables[0]);
dataset.Tables[0].Clear();
}
}
sd.Update(dataset.Tables[0]);
dataset.Tables[0].Clear();
sd.Dispose();
dataset.Dispose();
conn.Close();
}
TimeSpan ts = DateTime.Now - begin;
MessageBox.Show("ts = " + ts.TotalMilliseconds);
Bei diesem Test habe ich 28 Sekunden gebraucht, um 100.000 Daten einzufügen. Bei Batch-Updates und Beispielen für die Suche auf der ganzen Welt werden die Datensätze jedoch in das DataSet eingefügt und dann werden die Zeilen extrahiert.
Was meinen Test mit einer kleinen Datenmenge betrifft, funktioniert das Einfüllen von 100.000 Daten in das DataSet nicht mehr. Wenn es Millionen sind, wie müssen Sie es zuerst abrufen? in das DataSet eingefügt? Mit anderen Worten, welche Datensätze, die ich aktualisieren möchte, müssen ausgewählt werden, um diese Datensätze abzufragen?
Daher verwende ich immer noch eine leere DataTable, um die zu aktualisierenden Datensätze hinzuzufügen:
sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest where 1=0", conn);
//Die Bedingung 1=0 garantiert eine leere Tabelle.
sd.UpdateCommand = new SqlCommand("update CurrentTest set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
for(int i=0;i<300;i++){
.................................
dataset.Tables[0].Rows.Add(row);
}
sd.Update(dataset.Tables[0]);
Versuchen Sie zunächst, 300 Datensätze zu aktualisieren. In einer Schleife werden jedoch alle Datensätze aktualisiert. Für den Einfügevorgang wird jedoch angezeigt, dass „InsertCommand“ und dann „Zeile hinzufügen“ erforderlich sind.
Wenn zu diesem Zeitpunkt ein Update an die Datenbank gesendet wird, wird der Einfügevorgang ausgeführt und kann nicht aktualisiert werden.
for(int i=0;i<300;i++){
.................................
row = {Initialisierten Wert eingeben};
dataset.Tables[0].Rows.Add(row);
}
dataset.AcceptChanges();
for(int i=0;i<300;i++){
.................................
dataset.Tables[0].Rows[i][x] = "xxxxxxx";
.................................
}
sd.Update(dataset.Tables[0]);
Fügen Sie zuerst Daten in die DataTable ein, verwenden Sie dann AcceptChanges(), um den RowState in UnChanged zu ändern, und ändern Sie dann die Daten in der Tabelle, um den UnChanged-Status zu ändern.
Ändern Sie die Datentabelle vom aktuellen Status in „Original“ und aktualisieren Sie dann die Zeile der Datentabelle, die Sie verwenden können
Das Update ist erfolgreich, aber es ist wirklich unpraktisch.
Passen Sie die Idee an, nehmen Sie zunächst 200 Einträge aus der Datenbank (die Größe der Stapelaktualisierung) und erhalten Sie direkt eine Original-Datentabelle.
sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);
DataSet dataset = new DataSet();
sd.Fill(dataset);
Verwenden Sie diese 200 Leerzeichen, um andere zu aktualisierende Daten einzufügen und Folgendes zu sehen:
for (int i = 0; i < 100; i++)
{
dataset.Tables[0].Rows[i].BeginEdit();
dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
dataset.Tables[0].Rows[i]["data_value"] = 100;
dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//Datensätze von DEVID10000 auf DEVID10200 aktualisieren
dataset.Tables[0].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[0]);
OK, Erfolg, haha. Füllen Sie die zu aktualisierenden Daten weiterhin in diesen Bereich ein und senden Sie ihn, wenn er voll ist. Auf diese Weise dauert es nur wenige Zyklen, um 100.000 Daten zu aktualisieren.
DateTime begin = DateTime.Now;
string ConnectionString = "";
using(SqlConnection conn = new SqlConnection(connectionString))...{
conn.Open();
SqlDataAdapter sd = new SqlDataAdapter();
sd.SelectCommand = new SqlCommand("select top 200 devid,data_time,data_value from CurrentTest", conn);
DataSet dataset = new DataSet();
sd.Fill(dataset);
Zufällig r = new Random(1000);
sd.UpdateCommand = new SqlCommand("aktualisieren Sie CurrentTest "
+ " set data_time = @data_time,data_value = @data_value where devid = @devid", conn);
sd.UpdateCommand.Parameters.Add("@data_time", SqlDbType.Char, 19, "data_time");
sd.UpdateCommand.Parameters.Add("@data_value", SqlDbType.Int, 4, "data_value");
sd.UpdateCommand.Parameters.Add("@devid", SqlDbType.Char, 20, "devid");
sd.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;
sd.UpdateBatchSize = 0;
for (int count = 0; count < 100000;)
...{
for (int i = 0; i < 200; i++,count++)
...{
dataset.Tables[0].Rows[i].BeginEdit();
dataset.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
dataset.Tables[0].Rows[i]["data_value"] = 100;
dataset.Tables[0].Rows[i]["devid"] = "DEVID"+count;
dataset.Tables[0].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[0]);
}
dataset.Tables[0].Clear();
sd.Dispose();
dataset.Dispose
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html