好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

关于批量数据更新的问题(C#高性能)

关于批量数据更新的问题(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   博主以及同事和你共同探讨感兴趣的话题。

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于关于批量数据更新的问题(C#高性能)的详细内容...

  阅读:53次