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


            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();

  • 相关阅读:
    Kafka 再均衡监听器示例
    Spring boot中异步线程池
    【Java&Go并发编程系列】4.等待一组并发任务完成——CountDownLatch VS sync.WaitGroup
    Redis常用命令对应到Redisson对象操作
    Redisson教程
    Redisson官方文档
    Springboot 防止XSS攻击,包含解决RequestBody 的Json 格式参数
    防止XSS脚本注入-前端vue、后端springboot
    在Intellij IDEA中使用Debug
    appium 处理webview
  • 原文地址:https://www.cnblogs.com/smartsmile/p/6234221.html
Copyright © 2020-2023  润新知