優化前:
批量對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=SHEN\SQL2012;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
