Para la inserción y actualización de datos masivos, ADO.NET no es tan bueno como JDBC. Tiene un modelo unificado para operaciones por lotes.
PreparedStatement ps = conn.prepareStatement("insertar o actualizar arg1,args2....");
entonces puedes
para(int i=0;i<1000000000000000;i++){
ps.setXXX(realArg);
.....
ps.addBatch();
if(i%500==0){ //Supongamos que se envían quinientos elementos una vez
ps.executeBatch();
//borrar lote de parámetros
}
}
ps.executeBatch();
Esta operación no solo brinda un rendimiento extremadamente alto, sino que también es muy conveniente. Normalmente, en ADO.NET, para implementar dicha función, las API Addbat y CommitBat deben proporcionarse directamente en la interfaz Command o DataAdapter, pero ADO. NET Pero no se implementa de manera tan simple, sino que requiere que los desarrolladores adopten soluciones complejas.
Para una gran cantidad de operaciones de inserción, puede usar una tabla de datos vacía para agregar las filas que se insertarán y luego borrar la tabla después de una cierta cantidad de envíos.
No es demasiado complicado de implementar:
Fecha y hora comienzo = Fecha y hora.Ahora;
conexión de cadenaCadena = ...;
usando (conexión SqlConnection = nueva SqlConnection (cadena de conexión))...{
conexión.Open();
SqlDataAdapter sd = nuevo SqlDataAdapter();
sd.SelectCommand = new SqlCommand("seleccione devid,data_time,data_value de CurrentTest", conn);
sd.InsertCommand = new SqlCommand("insertar en CurrentTest (devid,data_time,data_value) "
+ "valores (@devid,@data_time,@data_value);", conexión);
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;
Conjunto de datos conjunto de datos = nuevo conjunto de datos();
sd.Fill(conjunto de datos);
Aleatorio r = nuevo Aleatorio(1000);
para (int i = 0; i < 100000; i++) ...{
objeto[] fila = ...{"DEVID"+i,DateTime.Now.ToString("aaaa-MM-dd HH:mm:ss"),r.Next(1,1000) };
conjunto de datos.Tables[0].Rows.Add(fila);
si (yo % 300 == 0) ...{
sd.Update(conjunto de datos.Tables[0]);
conjunto de datos.Tables[0].Clear();
}
}
sd.Update(conjunto de datos.Tables[0]);
conjunto de datos.Tables[0].Clear();
sd.Dispose();
conjunto de datos.Dispose();
conexión.Cerrar();
}
TimeSpan ts = DateTime.Now - comenzar;
MessageBox.Show("ts = " + ts.TotalMillisegundos);
Para esta prueba, me tomó 28 segundos insertar 100.000 datos. El rendimiento es bastante impresionante, pero para las actualizaciones por lotes y los ejemplos de búsqueda en todo el mundo, los registros se completan en el conjunto de datos y luego se extraen las filas.
Para actualizar, en lo que respecta a mi prueba con una pequeña cantidad de datos, completar 100.000 datos en el DataSet ya no funciona. Si son millones, ¿cómo se opera? ¿Primero debe obtener los registros? agrupados en el conjunto de datos? En otras palabras, ¿qué registros quiero actualizar deben seleccionarse para consultar estos registros?
Entonces sigo usando un DataTable vacío para agregar los registros que se actualizarán:
sd.SelectCommand = new SqlCommand("seleccione devid,data_time,data_value de CurrentTest donde 1=0", conn);
//La condición de 1=0 garantiza una tabla vacía.
sd.UpdateCommand = new SqlCommand("actualizar CurrentTest set data_time = @data_time,data_value = @data_value donde 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;
para(int i=0;i<300;i++){
............................
conjunto de datos.Tables[0].Rows.Add(fila);
}
sd.Update(conjunto de datos.Tables[0]);
Intente actualizar 300 registros primero. Si tiene éxito, actualizará todos los registros en un bucle, pero le indicará que la operación de inserción requiere InsertCommand porque es una tabla vacía y luego la operación Agregar fila. En este momento, se agrega RowState.
Si se envía Actualización a la base de datos en este momento, se realiza la operación de inserción y no se puede actualizar. Cambiar a:
para(int i=0;i<300;i++){
............................
fila = {completar el valor inicializado};
conjunto de datos.Tables[0].Rows.Add(fila);
}
conjunto de datos.AcceptChanges();
para(int i=0;i<300;i++){
............................
conjunto de datos.Tables[0].Rows[i][x] = "xxxxxxx";
............................
}
sd.Update(conjunto de datos.Tables[0]);
Primero inserte datos en DataTable, luego use AcceptChanges () para modificar RowState a UnChanged y luego modifique los datos en la tabla para cambiar el estado UnChanged.
Cambie el DataTable del estado actual al Original y luego actualice la fila del DataTable, puede usar
La actualización es exitosa, pero es realmente un inconveniente hacerlo.
Ajuste la idea, primero tome 200 entradas de la base de datos (el tamaño de la actualización por lotes) y obtenga directamente una DataTable original.
sd.SelectCommand = new SqlCommand("seleccione los 200 principales devid,data_time,data_value de CurrentTest", conn);
Conjunto de datos conjunto de datos = nuevo conjunto de datos();
sd.Fill(conjunto de datos);
Utilice estos 200 espacios para poner otros datos a actualizar y ver:
para (int i = 0; i < 100; i++)
{
conjunto de datos.Tables[0].Rows[i].BeginEdit();
conjunto de datos.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
conjunto de datos.Tables[0].Rows[i]["data_value"] = 100;
dataset.Tables[0].Rows[i]["devid"] = "DEVID"+(i+10000);//Actualizar registros de DEVID10000 a DEVID10200
conjunto de datos.Tables[0].Rows[i].EndEdit();
}
sd.Update(conjunto de datos.Tables[0]);
Bien, éxito, jaja. Sigue completando los datos para actualizar en este espacio y envíalo cuando esté lleno. De esta manera, solo se necesitan unos pocos ciclos para actualizar 100.000 datos.
Fecha y hora comienzo = Fecha y hora.Ahora;
conexión de cadenaCadena = "";
usando (conexión SqlConnection = nueva SqlConnection (cadena de conexión))...{
conexión.Open();
SqlDataAdapter sd = nuevo SqlDataAdapter();
sd.SelectCommand = new SqlCommand("seleccione los 200 principales devid,data_time,data_value de CurrentTest", conn);
Conjunto de datos conjunto de datos = nuevo conjunto de datos();
sd.Fill(conjunto de datos);
Aleatorio r = nuevo Aleatorio(1000);
sd.UpdateCommand = new SqlCommand("actualizar CurrentTest "
+ " set data_time = @data_time,data_value = @data_value donde 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;
para (int recuento = 0; recuento < 100000;)
...{
para (int i = 0; i < 200; i++,count++)
...{
conjunto de datos.Tables[0].Rows[i].BeginEdit();
conjunto de datos.Tables[0].Rows[i]["data_time"] = "2222-22-22 22:22:22";
conjunto de datos.Tables[0].Rows[i]["data_value"] = 100;
conjunto de datos.Tables[0].Rows[i]["devid"] = "DEVID"+count;
conjunto de datos.Tables[0].Rows[i].EndEdit();
}
sd.Update(conjunto de datos.Tables[0]);
}
conjunto de datos.Tables[0].Clear();
sd.Dispose();
conjunto de datos.Dispose
http://www.cnblogs.com/Seabiscuit/archive/2010/05/25/1743341.html