启用事务操作,解决批量插入或更新sqlite,mssql等数据库耗时问题 分类: .NET 2015-06-18 14:39 31人阅读 评论(0) 收藏

原文地址:http://blog.csdn.net/smartsmile2012/article/details/22167179


  1. private void button1_Click(object sender, EventArgs e)  
  2. {  
  3.     //Sqlite使用事务批量操作 极大的提高速度  
  4.     DateTime starttime = DateTime.Now;  
  5.     using (SQLiteConnection con = new SQLiteConnection(connStr))  
  6.     {  
  7.         con.Open();  
  8.         DbTransaction trans = con.BeginTransaction();//开始事务       
  9.         SQLiteCommand cmd = new SQLiteCommand(con);  
  10.         try  
  11.         {  
  12.             cmd.CommandText = "INSERT INTO MyTable(username,useraddr,userage) VALUES(@a,@b,@c)";  
  13.             for (int n = 0; n < 100000; n++)  
  14.             {  
  15.                 cmd.Parameters.Add(new SQLiteParameter("@a", DbType.String)); //MySql 使用MySqlDbType.String  
  16.                 cmd.Parameters.Add(new SQLiteParameter("@b", DbType.String)); //MySql 引用MySql.Data.dll  
  17.                 cmd.Parameters.Add(new SQLiteParameter("@c", DbType.String));  
  18.                 cmd.Parameters["@a"].Value = "张三" + n;  
  19.                 cmd.Parameters["@b"].Value = "深圳" + n;  
  20.                 cmd.Parameters["@c"].Value = 10 + n;  
  21.                 cmd.ExecuteNonQuery();  
  22.             }  
  23.             trans.Commit();//提交事务    
  24.             DateTime endtime = DateTime.Now;  
  25.             MessageBox.Show("插入成功,用时" + (endtime - starttime).TotalMilliseconds);  
  26.   
  27.         }  
  28.         catch(Exception ex)  
  29.         {  
  30.             MessageBox.Show(ex.Message);  
  31.         }  
  32.     }  
  33. }  
  1. //MySql 事务批量提交 极大提交速度  
  2. try  
  3. {  
  4.     using (MySqlConnection con = new MySqlConnection(MySqlStr))  
  5.     {  
  6.     con.Open();  
  7.     DbTransaction trans = con.BeginTransaction();//开始事务    
  8.  
  9.     #region 防重复先删除  
  10.     //循环本地Sqlite数据库数据  
  11.     for (int i = 0; i < count; i++)  
  12.     {  
  13.         DataRow dr = ds.Tables[0].Rows[i];  
  14.         string sqlDelete = "delete from packect where proimei=@d";  
  15.         MySqlCommand cmd1 = new MySqlCommand(sqlDelete, con);                             
  16.         cmd1.Parameters.Add(new MySqlParameter("@d", MySqlDbType.String));  
  17.         cmd1.Parameters["@d"].Value = dr["proimei"];  
  18.         cmd1.ExecuteNonQuery();  
  19.     }  
  20.     #endregion  
  21.  
  22.  
  23.     #region 新增数据  
  24.     //循环本地Sqlite数据库数据  
  25.     for (int i = 0; i < count; i++)  
  26.     {  
  27.         DataRow dr = ds.Tables[0].Rows[i];  
  28.         string sqlInsert = "insert into packect(proimei, prokg, proadddate) values(@a,@b,@c)";  
  29.         MySqlCommand cmd2 = new MySqlCommand(sqlInsert, con);    
  30.         cmd2.Parameters.Add(new MySqlParameter("@a", MySqlDbType.String));  
  31.         cmd2.Parameters.Add(new MySqlParameter("@b", MySqlDbType.Decimal));  
  32.         cmd2.Parameters.Add(new MySqlParameter("@c", MySqlDbType.DateTime));  
  33.         cmd2.Parameters["@a"].Value = dr["proimei"];  
  34.         cmd2.Parameters["@b"].Value = dr["prokg"];  
  35.         cmd2.Parameters["@c"].Value = dr["proadddate"];  
  36.         cmd2.ExecuteNonQuery();  
  37.     }  
  38.     #endregion  
  39.   
  40.     trans.Commit();//提交事务      
  41.     DateTime endtime = DateTime.Now;  
  42.     MessageBox.Show("上传数据成功,用时" + (endtime - starttime).TotalMilliseconds + "毫秒!");  
  43.     //清空本地数据库  
  44.     SQLiteHelper.ExecuteNonQuery(connStr, "delete from table1", CommandType.Text);  
  45.     }  
  46. }  
  47. catch (Exception ex)  
  48. {  
  49.     MessageBox.Show(ex.Message);  
  50. }  
  1. /* 
  2.     DataTable dt = new DataTable(); 
  3.     //定义需要插入的字段,字段名需跟数据库字段保持一致 
  4.     dt.Columns.Add("username"); 
  5.     dt.Columns.Add("useraddr"); 
  6.     dt.Columns.Add("userage"); 
  7.     for (int i = 0; i < 10000; i++) 
  8.     { 
  9.         dt.Rows.Add("张三" + i, "深圳" + i, i); 
  10.     } 
  11.     DateTime starttime = DateTime.Now; 
  12.     SqlBulkCopyInsert(dt, "mytable"); 
  13.     DateTime endtime = DateTime.Now; 
  14.     Response.Write("插入成功,用时" + (endtime - starttime).TotalSeconds + "秒");      
  15.  */  
  16. /// <summary>      
  17. /// 使用SqlBulkCopy批量插入,只限SQLServer,超大数据量快速导入       
  18. /// </summary>      
  19. /// <param name="table">填充的DataTable,支持其它数据源,请看重载</param>      
  20. /// <param name="tableName">数据库对应表名</param>        
  21. public void SqlBulkCopyInsert(DataTable table, string tableName)  
  22. {  
  23.     SqlBulkCopy sbc = new SqlBulkCopy(MSCL.Until.GetApp("SqlConnStr"));  
  24.     sbc.DestinationTableName = tableName;  
  25.   
  26.     for (int i = 0; i < table.Columns.Count; i++)  
  27.     {  
  28.         sbc.ColumnMappings.Add(table.Columns[i].ColumnName, table.Columns[i].ColumnName);  
  29.     }  
  30.     sbc.WriteToServer(table);  
  31. }   
  1. /// <summary>    
  2. /// 使用SqlBulkCopy批量插入,只限SQLServer,超大数据量快速导入    
  3. /// 缺点,没有返回行数    
  4. /// </summary>    
  5. /// <param name="table">填充的DataTable,支持其它数据源,请看重载</param>    
  6. /// <param name="tableName">数据库对应表名</param>    
  7. /// <param name="columns">插入表对应的列名集合</param>    
  8. public void SqlBulkCopyInsert(DataTable table, string tableName, string[] columns)  
  9. {  
  10.     SqlBulkCopy sbc = new SqlBulkCopy("接连字符串");  
  11.     sbc.DestinationTableName = tableName;  
  12.     foreach (string col in columns)  
  13.     {  
  14.         sbc.ColumnMappings.Add(col, col);  
  15.     }  
  16.     sbc.WriteToServer(table);  
  17. }  
  18.   
  19.   
  20. /// <summary>    
  21. /// 多行插入,Connection/Command/DataAdapter看你连接的数据库类型    
  22. /// 进行相应的替换即可    
  23. /// </summary>    
  24. /// <param name="ds">填充数据后的数据集</param>    
  25. /// <returns>受影响行数</returns>    
  26. public int MultyInsert(DataSet ds)  
  27. {  
  28.     int result = 0;  
  29.     IDbConnection con = new OracleConnection("连接字符串");  
  30.     con.Open();  
  31.     IDbCommand cmd = new OracleCommand();  
  32.     cmd.CommandText = "Insert into Member(UserName,Password) values(@name,@password)";  
  33.     IDbDataParameter namePar = cmd.CreateParameter();  
  34.     namePar.ParameterName = "@name";  
  35.     namePar.SourceColumn = "UserName";  
  36.     namePar.SourceVersion = DataRowVersion.Original;  
  37.     namePar.DbType = DbType.String;  
  38.     cmd.Parameters.Add(namePar);  
  39.   
  40.     IDbDataParameter passPar = cmd.CreateParameter();  
  41.     passPar.ParameterName = "@pass";  
  42.     passPar.DbType = DbType.String;  
  43.     passPar.SourceColumn = "Password";  
  44.     passPar.SourceVersion = DataRowVersion.Original;  
  45.     cmd.Parameters.Add(passPar);  
  46.   
  47.     IDbDataAdapter adpt = new OracleDataAdapter();  
  48.     adpt.InsertCommand = cmd;  
  49.     try  
  50.     {  
  51.         result = adpt.Update(ds);  
  52.     }  
  53.     catch (Exception)  
  54.     {  
  55.   
  56.         throw;  
  57.     }  
  58.     finally  
  59.     {  
  60.         con.Close();  
  61.     }  
  62.     return result;  
  63. }    
  1. /* 
  2.  * Oracle中非常强大快速的数据批量操作方法 
  3. */  
  4. ////引用  
  5. //using System.Data;  
  6. //using System.Data.OracleClient;  
  7. //using Oracle.DataAccess.Client; //Oracle自带数据访问组件 位置: $Oracle安装路径$/bin/Oracle.DataAccess.dll  
  8. //设置一个数据库的连接串  
  9. string connectStr = "User Id=scott;Password=tiger;Data Source=";  
  10. OracleConnection conn = new OracleConnection(connectStr);  
  11. OracleCommand command = new OracleCommand();  
  12. command.Connection = conn;  
  13. //到此为止,还都是我们熟悉的代码,下面就要开始喽  
  14. //这个参数需要指定每次批插入的记录数  
  15. int recc = 10000000;  
  16. command.ArrayBindCount = recc;  
  17. //在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候  
  18. //用到的是数组,而不是单个的值,这就是它独特的地方  
  19. command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";  
  20. conn.Open();  
  21. //下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出  
  22. int[] deptNo = new int[recc];  
  23. string[] dname = new string[recc];  
  24. string[] loc = new string[recc];  
  25. // 为了传递参数,不可避免的要使用参数,下面会连续定义三个  
  26. // 从名称可以直接看出每个参数的含义,不在每个解释了  
  27. OracleParameter deptNoParam = new OracleParameter("deptno", OracleType.Int32);  
  28. deptNoParam.Direction =  ParameterDirection.Input;  
  29. deptNoParam.Value = deptNo;  
  30. command.Parameters.Add(deptNoParam);  
  31. OracleParameter deptNameParam = new OracleParameter("deptname", OracleType.VarChar);  
  32. deptNameParam.Direction = ParameterDirection.Input;  
  33. deptNameParam.Value = dname; command.Parameters.Add(deptNameParam);  
  34. OracleParameter deptLocParam = new OracleParameter("loc", OracleType.VarChar);  
  35. deptLocParam.Direction = ParameterDirection.Input;  
  36. deptLocParam.Value = loc;  
  37. command.Parameters.Add(deptLocParam);  
  38. //在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL  
  39. for (int i = 0; i < recc; i++)  
  40. {  
  41.     deptNo[i] = i;  
  42.     dname[i] = i.ToString();  
  43.     loc[i] = i.ToString();  
  44. }  
  45. //这个调用将把参数数组传进SQL,同时写入数据库  
  46. command.ExecuteNonQuery();  
posted @ 2015-06-18 14:39  哲夫  阅读(230)  评论(0编辑  收藏  举报