zoukankan      html  css  js  c++  java
  • 关于批量数据更新的问题(C#高性能)

    当你批量操作数据的时候,常常会使用到update table1 from table2)的这种方式。这种方式是最简洁的。

    但当你从excel或者CSV文件更新海量数据时,再使用这种方法,那性能是不是好,字符串拼接又何其之多,大数据是不是需要分组更新?

    我不想去检测各种方法的速度,因为我个人比较认可以下方式,欢迎大家批评与指正。

    我需要使用到的类主要是SqlCommandBuilder。

    /// <param name="table">准备更新的DataTable新数据</param>
        /// <param name="TableName">对应要更新的数据库表名</param>
        /// <param name="primaryKeyName">对应要更新的数据库表的主键名</param>
        /// <param name="columnsName">对应要更新的列的列名集合</param>
        /// <param name="limitColumns">需要在SQL的WHERE条件中限定的条件字符串,可为空。</param>
        /// <param name="onceUpdateNumber">每次往返处理的行数</param>
        /// <returns>返回更新的行数</returns>
        public static int Update(DataTable table, string TableName, string primaryKeyName, string[] columnsName, string limitWhere,int onceUpdateNumber)
        {
            if (string.IsNullOrEmpty(TableName)) return 0;
            if (string.IsNullOrEmpty(primaryKeyName)) return 0;
            if (columnsName == null || columnsName.Length <= 0) return 0;
            DataSet ds = new DataSet();
            ds.Tables.Add(table);
            int result = 0;
            using (SqlConnection sqlconn = new SqlConnection(SqlHelper.ConnString))
            {
                sqlconn.Open();
    
                //使用加强读写锁事务   
                SqlTransaction tran = sqlconn.BeginTransaction(IsolationLevel.ReadCommitted);
                try
                {
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        //所有行设为修改状态   
                        dr.SetModified();
                    }
                    //为Adapter定位目标表   
                    SqlCommand cmd = new SqlCommand(string.Format("select * from {0} where {1}", TableName,limitWhere), sqlconn, tran);
                    SqlDataAdapter da = new SqlDataAdapter(cmd);
                    SqlCommandBuilder sqlCmdBuilder = new SqlCommandBuilder(da);
                    da.AcceptChangesDuringUpdate = false;
                    string columnsUpdateSql = "";
                    SqlParameter[] paras = new SqlParameter[columnsName.Length];
                    //需要更新的列设置参数是,参数名为"@+列名"
                    for (int i = 0; i < columnsName.Length; i++)
                    {
                        //此处拼接要更新的列名及其参数值
                        columnsUpdateSql += ("[" + columnsName[i] + "]" + "=@" + columnsName[i] + ",");
                        paras[i] = new SqlParameter("@" + columnsName[i], columnsName[i]);
                    }
                    if (!string.IsNullOrEmpty(columnsUpdateSql))
                    {
                        //此处去掉拼接处最后一个","
                        columnsUpdateSql = columnsUpdateSql.Remove(columnsUpdateSql.Length - 1);
                    }
                    //此处生成where条件语句
                    string limitSql = ("[" + primaryKeyName + "]" + "=@" + primaryKeyName);
                    SqlCommand updateCmd = new SqlCommand(string.Format(" UPDATE [{0}] SET {1} WHERE {2} ", TableName, columnsUpdateSql, limitSql));
                    //不修改源DataTable   
                    updateCmd.UpdatedRowSource = UpdateRowSource.None;
                    da.UpdateCommand = updateCmd;
                    da.UpdateCommand.Parameters.AddRange(paras);
                    da.UpdateCommand.Parameters.Add("@" + primaryKeyName, primaryKeyName);
                    //每次往返处理的行数
                    da.UpdateBatchSize = onceUpdateNumber;
                    result = da.Update(ds,TableName);
                    ds.AcceptChanges();
                    tran.Commit();
    
                }
                catch
                {
                    tran.Rollback();
                }
                finally
                {
                    sqlconn.Dispose();
                    sqlconn.Close();
                }
    
    
            }
            return result;
        }

    注: 此方法调用时要传入的参数,包括主键名和列名都应与数据库实际的名称相对应.
    你可以不传入限定的where条件,如果传入,只需传入:Name="chamy" or Name="jundy",不需加入“where”等字符,不可以在此处传入主键的限定。你只需要在主键名这个参数上传入名称即可。

    更多WEB开发技术请加群:Asp.Net高级群 号码:261882616  博主以及同事和你共同探讨感兴趣的话题。

  • 相关阅读:
    Day 20 初识面向对象
    Day 16 常用模块
    Day 15 正则表达式 re模块
    D14 模块 导入模块 开发目录规范
    Day 13 迭代器,生成器,内置函数
    Day 12 递归,二分算法,推导式,匿名函数
    Day 11 闭包函数.装饰器
    D10 函数(二) 嵌套,命名空间作用域
    D09 函数(一) 返回值,参数
    Day 07 Day08 字符编码与文件处理
  • 原文地址:https://www.cnblogs.com/lilin123/p/2752165.html
Copyright © 2011-2022 走看看