文档章节

启用事务操作,解决批量插入或更新sqlite,mssql等数据库耗时问题

深圳大道
 深圳大道
发布于 2016/12/29 15:36
字数 1111
阅读 4
收藏 0
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();

本文转载自:http://blog.csdn.net/smartsmile2012/article/details/22167179

深圳大道
粉丝 3
博文 877
码字总数 0
作品 0
深圳
架构师
私信 提问
数据库访问之Sqlite的不同之处

在我的Winform开发框架中,底层的数据访问支持多种不同的数据库,在数据库访问的开发过程中,发现Sqlite多数情况下,操作都和SqlServer或者说是和标准Sql差不多的。当然,Sqlite本身也有一些...

长平狐
2012/08/22
108
0
数据库访问之Sqlite的不同之处

在我的Winform开发框架中,底层的数据访问支持多种不同的数据库,在数据库访问的开发过程中,发现Sqlite多数情况下,操作都和SqlServer或者说是和标准Sql差不多的。当然,Sqlite本身也有一些...

长平狐
2012/06/11
80
0
ServerSuperIO v3.6.4 发布,支持 mysql 等的持久化

概述: ServerSuperIO支持设备驱动和OPC Client采集的数据信息按标签集合写入mysql、oracle、sqlserver和sqlite数据库。现在还支持写入实时数据库,例如:edna、golden和corert等。同时支持实...

wxzz
2017/05/12
1K
1
.NET Chloe.ORM v2.3,支持 sql 拦截器

Chloe.ORM:一款高质量的.Net C#数据库访问框架(ORM)。支持SqlServer、MySql、Oracle及SQLite,实体为纯POCO,支持基本数据类映射的同时也支持枚举类型。查询接口借鉴linq,支持lambda表达式...

so_while
2017/01/09
1K
9
.NET Chloe.ORM v2.8 CURD 支持指定表名

Chloe.ORM:一款高质量的.Net C#数据库访问框架(ORM)。支持SqlServer、MySql、Oracle及SQLite,实体为纯POCO,支持基本数据类映射的同时也支持枚举类型。查询接口借鉴linq,支持lambda表达式...

so_while
2017/06/05
893
5

没有更多内容

加载失败,请刷新页面

加载更多

PostgreSQL 11.3 locking

rudi
今天
5
0
Mybatis Plus sql注入器

一、继承AbstractMethod /** * @author beth * @data 2019-10-23 20:39 */public class DeleteAllMethod extends AbstractMethod { @Override public MappedStatement injectMap......

一个yuanbeth
今天
12
1
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
今天
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
今天
9
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
今天
81
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部