优化前:
批量对1000条数据的进行插入 和 更新的操作~执行速度慢(表数据量大,字段多~~这不在本文优化之内,另外优化处理~~~),也没有等待提示~~点一下等好久没任何反应~~半天过去了 提示操成功~~脾气躁一点 啪啪啪点几下 系统卡死GG了~~
优化后:
执行时加入操作等待提示~~执行后增加耗时展示~~但这都不是本文重点~~略过~~
大概看了下现有的程序对1000条数据打执行,就是循环1000个更改+1000个插入~根数据库交互2000次~~不慢才怪~~
批量更新:使用SqlDataAdapter.Update(DateTable)
批量插入:使用SqlBulkCopy
都9012年了还ado.net ~~不过执行效率确实提高一倍以上~~不知道这代码还有没有人去用了 ~~
demo奉上~~~
using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 批量插入更新数据 { class Program { static void Main(string[] args) { DateTime dt1 = System.DateTime.Now; string connStr = @"server=SHENSQL2012;uid=sa;pwd=123456;database=LmhsDB"; using (SqlConnection con = new SqlConnection(connStr)) { con.Open(); SqlTransaction tran = con.BeginTransaction(); try { //批量插入 Inserts(con, tran); Updates(con, tran); tran.Commit(); } catch { tran.Rollback(); } } DateTime dt2 = System.DateTime.Now; TimeSpan ts = dt2.Subtract(dt1); Console.WriteLine("耗时:" + Convert.ToDouble(ts.TotalMilliseconds / 1000) + "秒"); Console.ReadLine(); } public static void Inserts(SqlConnection con, SqlTransaction tran) { DataTable dtIns = new DataTable(); //首先查出一张空表 作为模版(注意主键自增问题:SqlBulkCopyOptions.KeepNulls) SqlCommand sqlIns = new SqlCommand("select ID,UserName,Gender,CreateTime " + " FROM InsertTest where 1=0 ", con, tran); SqlDataAdapter sdaIns = new SqlDataAdapter(); sdaIns.SelectCommand = sqlIns; sdaIns.Fill(dtIns); //插入1000条 for (int i = 0; i < 1000; i++) { DataRow dataRow = dtIns.NewRow(); dataRow[0] = 0; dataRow[1] = "我叫" + Guid.NewGuid(); dataRow[2] = "男"; dataRow[3] = DateTime.Now; dtIns.Rows.Add(dataRow); } using (SqlBulkCopy sqlBulkIns = new SqlBulkCopy(con, SqlBulkCopyOptions.KeepNulls, tran)) { sqlBulkIns.DestinationTableName = "InsertTest"; sqlBulkIns.BatchSize = dtIns.Rows.Count; if (dtIns != null && dtIns.Rows.Count != 0) { sqlBulkIns.WriteToServer(dtIns); } } sqlIns.Dispose(); } public static void Updates(SqlConnection con, SqlTransaction tran) { DataSet ds = new DataSet(); SqlDataAdapter sda = new SqlDataAdapter(); //先查询出一个模版放到DataSet,让更新Dataset中打数据 然后SqlDataAdapter.Update(Table)批量更新 SqlCommand sqlCommandSel = new SqlCommand("select top 1000 ID,UserName,Gender,CreateTime from InsertTest ", con, tran); sda.SelectCommand = sqlCommandSel; sda.Fill(ds); SqlCommand sqlCommandUp = new SqlCommand("Update InsertTest set UserName=@UserName,Gender=@Gender,CreateTime=@CreateTime where ID=@ID", con, tran); sda.UpdateCommand = sqlCommandUp; sda.UpdateCommand.Parameters.Add("@UserName", SqlDbType.VarChar, 100, "UserName"); sda.UpdateCommand.Parameters.Add("@Gender", SqlDbType.VarChar, 100, "Gender"); sda.UpdateCommand.Parameters.Add("@CreateTime", SqlDbType.DateTime, 0, "CreateTime"); sda.UpdateCommand.Parameters.Add("@ID", SqlDbType.NVarChar, 0, "ID"); sda.UpdateCommand.UpdatedRowSource = UpdateRowSource.None; sda.UpdateBatchSize = 0; //把模版中的数据修改后更新回去,实际上应该是你更新的业务数据集合 for (int count = 0; count < ds.Tables[0].Rows.Count; count++) { //对 System.Data.DataRow 对象开始编辑操作。 ds.Tables[0].Rows[count].BeginEdit(); ds.Tables[0].Rows[count]["UserName"] ="我是批量更改过的"; ds.Tables[0].Rows[count]["Gender"] = "男-批量更新的"; ds.Tables[0].Rows[count]["CreateTime"] = DateTime.Now; ds.Tables[0].Rows[count]["ID"] = ds.Tables[0].Rows[count]["ID"];//必须要保证dt中的Id在数据表中存在,否则会报错,比如dt中的Id=1000,那么数据表中也需要有一条Id=1000的数据 ds.Tables[0].Rows[count].EndEdit(); } int aa = sda.Update(ds.Tables[0]); sqlCommandSel.Dispose(); sqlCommandUp.Dispose(); } } }
https://gitee.com/pfr/InsertsOrUpdate
企鹅群:48904756