啟用事務操作,解決批量插入或更新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();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM