首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

求DataSet批量导入Mssql数据库的写法,该如何解决

2013-07-25 
求DataSet批量导入Mssql数据库的写法求DataSet批量导入Mssql数据库的写法数据库有张表table1 列名 (nvarch

求DataSet批量导入Mssql数据库的写法
求DataSet批量导入Mssql数据库的写法
数据库有张表table1 列名 (nvarchar)Name,(nvarchar)something;
DataSet从其它数据源读入数据,也是Name 和 something 2个列;
但是name 和 something 可能是其它类型,int, datatime,long 什么的,
就是列的类型不确定,然后把它们批量导入MSSQL数据库,
一条一条的导是沒问题,但是太慢了 5W条数据花了8分钟多,
用数据库SSIS测试了一下,5W条数据只花17-22s,
,批量导入这个该怎么做?
整了一天了,网上找的方法沒一个成功的- -
[解决办法]
你为什么不尝试跨库操作呢,通过sql从这个库把数据放到另一个库
[解决办法]
SqlBulkCopy 类
[解决办法]
第一步,填充一个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;
        }


[解决办法]

//.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";
  }

  }

热点排行