求DataSet批量导入Mssql数据库的写法
数据库有张表table1 列名 (nvarchar)Name,(nvarchar)something;
DataSet从其它数据源读入数据,也是Name 和 something 2个列;
但是name 和 something 可能是其它类型,int, datatime,long 什么的,
就是列的类型不确定,然后把它们批量导入MSSQL数据库,
一条一条的导是沒问题,但是太慢了 5W条数据花了8分钟多,
用数据库SSIS测试了一下,5W条数据只花17-22s,
,批量导入这个该怎么做?
整了一天了,网上找的方法沒一个成功的- -

解决方案 »

  1.   

    你为什么不尝试跨库操作呢,通过sql从这个库把数据放到另一个库
      

  2.   

    SqlBulkCopy 类
      

  3.   

    第一步,填充一个datatable,然后更新datatable就行了。
    下面是实例代码,跑通了的。
     public DataSet Insert_Datable()
            {
                SqlConnection con = new SqlConnection(Configuration.Conn);
                SqlDataAdapter sdp = new SqlDataAdapter();
                DataSet dt = new DataSet();
                SqlCommand comm = new SqlCommand();            comm.Connection = con;
                comm.CommandText = "select Names,Address,Pid,Image from  Users";
                sdp.SelectCommand = comm;//首先要指定selectitem,并且字段要指定清楚,和insert字段个数和名称一致
                SqlCommandBuilder scom = new SqlCommandBuilder(sdp);
                sdp.Fill(dt, "Users");            comm.CommandText = "Insert into Users values(@Pid,@Names,@Address,@Image)";
                SqlParameter[] pars = new SqlParameter[] { 
                 new SqlParameter("@Pid",SqlDbType.Int,4,"Pid")
                ,new SqlParameter("@Names",SqlDbType.VarChar,10,"Names")
                ,new SqlParameter("@Address",SqlDbType.NVarChar,20,"Address")
                ,new SqlParameter("@Image",SqlDbType.Image,200,"Image")
                };
                pars.ToList<SqlParameter>().ForEach(parm => comm.Parameters.Add(parm));            DataRow dr = null;
                for (int i = 1; i < 3; i++)
                {
                    dr = dt.Tables[0].NewRow();
                    dr["Names"] = "Jeep" + i.ToString();
                    dr["Address"] = "第" + i.ToString() + "街道";
                    dr["Pid"] = i + 8;
                    dt.Tables[0].Rows.Add(dr);
                }//通过对表值的修改,实现方法Update(table)            SqlCommandBuilder icom = new SqlCommandBuilder(sdp);
                sdp.InsertCommand = comm;//insert com语句
                sdp.Update(dt.Tables["Users"]);
                dt.AcceptChanges();
                return dt;
            }
      

  4.   


    //.net2.0中使用SqlBulkCopy进行大批量数据迁移,封装为通用类//在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,
    //还是进行不同数据源之间的迁移,都不是很方便。而在.Net2.0中,
    //SQLClient命名空间下增加了几个新类帮助我们通过DataTable或DataReader批量迁移数据。
    //数据源可以来自关系数据库或者XML文件,甚至WebService返回结果。
    //其中最重要的一个类就是SqlBulkCopy类,使用它可以很方便的帮助我们把数据源的数据迁移到目标数据库中。
    //下面我们先通过一个简单的例子说明这个类的使用:
    public class SqlBulkCopyEntity
      {  string lblCounter;  DateTime startTime;
      TimeSpan copyTime;
      public void Bulk(string srcConstr, string desConstr, ref string errorMsg)
      {
      startTime = DateTime.Now; //当前系统时间
      SqlConnection srcCon = new SqlConnection(srcConstr);
      //SqlConnection desCon = new SqlConnection(desConstr);
      SqlCommand srcCmd = new SqlCommand("select * from srctable", srcCon);
      SqlDataAdapter srcDa = new SqlDataAdapter(srcCmd);
      DataTable dt = new DataTable();
      srcDa.Fill(dt);
      //生成SqlBulkCopy实例,在构造函数中指定目标数据库,
      //使用SqlBulkCopyOptions.UseInternalTransaction是指迁移动指定作在一个Transaction中,如果数据迁移中产生错误或异常将发生回滚。
      SqlBulkCopy desBulk = new SqlBulkCopy(desConstr, SqlBulkCopyOptions.UseInternalTransaction);
      //指定操作完成的Timout超时时间
      desBulk.BulkCopyTimeout = 500000000;  //NotifyAfter属性指定通知通知事件前处理的数据行数,
      //在这里指定为表的行数,并添加SqlRowsCopied事件输出整个迁移过程的时间。
      //WriteToServer方法就是将数据源拷备到目标数据库。
      //在使用WriteToServer方法之前必须先指定DestinationTableName属性,
      //也就是目标数据库的表名,
      desBulk.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
      desBulk.NotifyAfter = dt.Rows.Count;  //我们还可以自己定义一个Transaction,例如:
      //SqlTransaction Transaction;
      //Transaction =
      //SrcCom.Connection.BeginTransaction();
      //SqlBulkCopy DesBulkOp;
      //DesBulkOp = new SqlBulkCopy(new SqlConnection(DesConString),
      //SqlBulkCopyOptions.Default,
      //Transaction);  //try
      //{
      // //..
      //}
      //catch { }
      //finally
      //{
      // Transaction.Commit();
      //}
      //另外还有一个SqlBulkCopyColumnMapping类,可以让数据源字段映射到目标数据中命名不同的字段上。也就是说如果目标数据和源数据的列名不同时,可以用这个类进行映射:
      //SqlBulkCopyColumnMapping ColMap = new SqlBulkCopyColumnMapping("SrcCol", "DesCol");
      //DesBulkOp.ColumnMappings.Add(ColMap);
      //或者可以直接添加映射:
      //DesBulkOp.ColumnMappings.Add("SrcCol", "DesCol");
      try
      {
      desBulk.DestinationTableName = dt.TableName;
      desBulk.WriteToServer(dt);//将数据拷贝到目标数据库,在使用WriteToServer之前必须指定DestinationTablename(目标数据库的表名)
      }
      catch (Exception ex)
      {
      errorMsg = ex.Message;
      }
      finally
      {
      #region 关闭连接
      srcCon.Close();
      //desCon.Close();
      #endregion
      }
      }  private void OnRowsCopied(object sender, SqlRowsCopiedEventArgs args)
      {
      lblCounter += args.RowsCopied.ToString() + "行被复制!rows are copied";
      copyTime = DateTime.Now - startTime;
      lblCounter += "Copy Time:" + copyTime.Seconds.ToString() + "." + copyTime.Milliseconds.ToString() + "秒!seconds";
      }  }
      

  5.   

    4楼的,用你的转数据源和目标源类型都一样的可以转,所有类型都换nvarchar 不知道为什么还是不行
    5楼的方法可以,由于目标源的数据库是断开的,我们是通过他们给我们的文件生成一个table的,
    所以改了下代码
    public void Bulk(DataSet Src, string desConstr)
            {
                startTime = DateTime.Now; //当前系统时间            DataTable dt = Src.Tables[0];
                
                //生成SqlBulkCopy实例,在构造函数中指定目标数据库,
                //使用SqlBulkCopyOptions.UseInternalTransaction是指迁移动指定作在一个Transaction中,如果数据迁移中产生错误或异常将发生回滚。
                SqlBulkCopy desBulk = new SqlBulkCopy(desConstr, SqlBulkCopyOptions.UseInternalTransaction);
                //指定操作完成的Timout超时时间
                desBulk.BulkCopyTimeout = 500000000;            //NotifyAfter属性指定通知通知事件前处理的数据行数,
                //在这里指定为表的行数,并添加SqlRowsCopied事件输出整个迁移过程的时间。
                //WriteToServer方法就是将数据源拷备到目标数据库。
                //在使用WriteToServer方法之前必须先指定DestinationTableName属性,
                //也就是目标数据库的表名,
                desBulk.SqlRowsCopied += new SqlRowsCopiedEventHandler(OnRowsCopied);
                desBulk.NotifyAfter = dt.Rows.Count;            
                try
                {
                    desBulk.DestinationTableName = dt.TableName;
                    desBulk.WriteToServer(dt);//将数据拷贝到目标数据库,在使用WriteToServer之前必须指定DestinationTablename(目标数据库的表名)
                }
                catch (Exception ex)
                {
                    //errorMsg = ex.Message;
                }
                //finally
                //{
                   // #region 关闭连接
                    //srcCon.Close();
                    //desCon.Close();
                   // #endregion
               // }
            }
    转了10W条的内容比较少的数据测试了一下,
    一条一条的转用6分钟多
    SSIS 2s-3s
    Bulk 用了6-7s
    这么速度已经满足了
      

  6.   

    支持楼上几位:SqlBulkCopy 类方式,性能很强
      

  7.   

    你的查询字段和插入字段,一致吗,一致的话,在添加parameter,就不会出错。