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