Pour l'insertion et la mise à jour de données massives, ADO.NET n'est en effet pas aussi bon que JDBC a un modèle unifié pour les opérations par lots. Il est très pratique à utiliser :
PreparedStatement ps = conn.prepareStatement("insérer ou mettre à jour arg1,args2....");
alors tu peux
pour(int i=0;i<1000000000000000;i++){
ps.setXXX(realArg);
.....
ps.addBatch();
if(i%500==0){ //Supposons que cinq cents éléments soient soumis une fois
ps.executeBatch();
//effacer le lot de paramètres
}
}
ps.executeBatch();
Une telle opération apporte non seulement des performances extrêmement élevées, mais est également très pratique. Habituellement, dans ADO.NET, pour implémenter une telle fonction, les API Addbat et CommitBat doivent être fournies directement dans l'interface Command ou dans l'interface DataAdapter, mais ADO. NET Mais il n'est pas implémenté aussi simplement, mais nécessite que les développeurs passent par des solutions de contournement complexes.
Pour un grand nombre d'opérations d'insertion, vous pouvez utiliser un DataTable vide pour ajouter les lignes à insérer, puis effacer la table après un certain nombre de soumissions.
Ce n’est pas trop compliqué à mettre en œuvre :
DateTime début = DateTime.Now ;
chaîne connexionString = ...;
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("insérer dans CurrentTest (devid,data_time,data_value) "
+ "valeurs (@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 ;
Ensemble de données DataSet = new DataSet();
sd.Fill (ensemble de données);
Aléatoire r = nouveau Aléatoire (1000) ;
pour (int i = 0; i < 100000; i++) ...{
object[] row = ...{"DEVID"+i,DateTime.Now.ToString("aaaa-MM-jj HH:mm:ss"),r.Next(1,1000) };
dataset.Tables[0].Rows.Add(ligne);
si (je % 300 == 0) ...{
sd.Update(dataset.Tables[0]);
jeu de données.Tables[0].Clear();
}
}
sd.Update(dataset.Tables[0]);
jeu de données.Tables[0].Clear();
sd.Dispose();
ensemble de données.Dispose();
conn.Close();
}
TimeSpan ts = DateTime.Now - commencer ;
MessageBox.Show("ts = " + ts.TotalMilliseconds);
Pour ce test, il m'a fallu 28 secondes pour insérer 100 000 éléments de données. Mais pour les mises à jour par lots et les exemples de recherche dans le monde entier, les enregistrements sont renseignés dans le DataSet puis les lignes sont extraites.
Pour mettre à jour, en ce qui concerne mon test avec une petite quantité de données, remplir 100 000 éléments de données dans le DataSet ne fonctionne plus s'il y en a des millions, comment l'exploiter ? regroupés dans le DataSet Medium ? En d'autres termes, quels enregistrements je souhaite mettre à jour doivent être sélectionnés pour interroger ces enregistrements ?
J'utilise donc toujours un DataTable vide pour ajouter les enregistrements à mettre à jour :
sd.SelectCommand = new SqlCommand("select devid,data_time,data_value from CurrentTest où 1=0", conn);
//La condition 1=0 garantit une table vide.
sd.UpdateCommand = new SqlCommand("mettre à jour CurrentTest set data_time = @data_time,data_value = @data_value où 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 ;
pour(int i=0;i<300;i++){
........................
dataset.Tables[0].Rows.Add(ligne);
}
sd.Update(dataset.Tables[0]);
Essayez d'abord de mettre à jour 300 enregistrements. Si cela réussit, il mettra à jour tous les enregistrements dans une boucle, mais il indiquera que l'opération d'insertion nécessite InsertCommand car il s'agit d'une table vide, puis l'opération d'ajout de ligne est ajoutée à ce moment-là.
Si la mise à jour est envoyée à la base de données à ce moment-là, l'opération d'insertion est effectuée et ne peut pas être mise à jour. Remplacez par :
pour(int i=0;i<300;i++){
........................
row = {remplir la valeur initialisée} ;
dataset.Tables[0].Rows.Add(ligne);
}
ensemble de données.AcceptChanges();
pour(int i=0;i<300;i++){
........................
dataset.Tables[0].Rows[i][x] = "xxxxxxx";
........................
}
sd.Update(dataset.Tables[0]);
Insérez d'abord les données dans le DataTable, puis utilisez AcceptChanges() pour modifier le RowState en UnChanged, puis modifiez les données de la table pour changer l'état UnChanged.
Modifiez le DataTable de l'état actuel à Original, puis mettez à jour la ligne du DataTable, vous pouvez utiliser
La mise à jour est réussie, mais ce n'est vraiment pas pratique.
Ajustez l'idée, prenez d'abord 200 entrées de la base de données (la taille de la mise à jour par lots) et obtenez directement un DataTable original.
sd.SelectCommand = new SqlCommand("sélectionner les 200 premiers devid,data_time,data_value de CurrentTest", conn);
Ensemble de données DataSet = new DataSet();
sd.Fill (ensemble de données);
Utilisez ces 200 espaces pour mettre d'autres données à mettre à jour et voir :
pour (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);//Mettre à jour les enregistrements de DEVID10000 vers DEVID10200
dataset.Tables[0].Rows[i].EndEdit();
}
sd.Update(dataset.Tables[0]);
OK, succès, haha. Continuez à remplir les données à mettre à jour dans cet espace et soumettez-les lorsqu'il est plein. De cette façon, il ne faut que quelques cycles pour mettre à jour 100 000 données.
DateTime début = DateTime.Now ;
chaîne connexionString = "";
using(SqlConnection conn = new SqlConnection(connectionString))...{
conn.Open();
SqlDataAdapter sd = new SqlDataAdapter();
sd.SelectCommand = new SqlCommand("sélectionner les 200 premiers devid,data_time,data_value de CurrentTest", conn);
Ensemble de données DataSet = new DataSet();
sd.Fill (ensemble de données);
Aléatoire r = nouveau Aléatoire (1000) ;
sd.UpdateCommand = new SqlCommand("mettre à jour CurrentTest"
+ " set data_time = @data_time,data_value = @data_value où 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 ;
pour (compte int = 0 ; compte < 100 000 ;)
...{
pour (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]);
}
jeu de données.Tables[0].Clear();
sd.Dispose();
ensemble de données.Dispose
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html