求DataSet批量导入Mssql数据库的写法

叫我三三 2011-05-18 02:38:18
求DataSet批量导入Mssql数据库的写法
数据库有张表table1 列名 (nvarchar)Name,(nvarchar)something;
DataSet从其它数据源读入数据,也是Name 和 something 2个列;
但是name 和 something 可能是其它类型,int, datatime,long 什么的,
就是列的类型不确定,然后把它们批量导入MSSQL数据库,
一条一条的导是沒问题,但是太慢了 5W条数据花了8分钟多,
用数据库SSIS测试了一下,5W条数据只花17-22s,
,批量导入这个该怎么做?
整了一天了,网上找的方法沒一个成功的- -
...全文
229 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
张春雷 2013-07-21
  • 打赏
  • 举报
回复
楼主同学。。。。。你有没有遇到这种情况啊 如果你的10W条数据中有错的话。。。导入就会终止了。。。。。而且错误前边的已经导入了。。。有没有想过做个数据验证啊
Daqing 2011-05-18
  • 打赏
  • 举报
回复
你的查询字段和插入字段,一致吗,一致的话,在添加parameter,就不会出错。
上帝的亲哥哥 2011-05-18
  • 打赏
  • 举报
回复
支持楼上几位:SqlBulkCopy 类方式,性能很强
叫我三三 2011-05-18
  • 打赏
  • 举报
回复
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
这么速度已经满足了
禁用F3 2011-05-18
  • 打赏
  • 举报
回复

高手呀
学习了...
叫我三三 2011-05-18
  • 打赏
  • 举报
回复
我测试一下
谢谢大家
yalan 2011-05-18
  • 打赏
  • 举报
回复

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

}
Daqing 2011-05-18
  • 打赏
  • 举报
回复
第一步,填充一个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;
}
龍过鸡年 2011-05-18
  • 打赏
  • 举报
回复
叫我三三 2011-05-18
  • 打赏
  • 举报
回复
我也想啊,问题数据库是别的企业的,只给了我们查询指定表权限,不准我们动他们数据库的任何东西
bdmh 2011-05-18
  • 打赏
  • 举报
回复
你为什么不尝试跨库操作呢,通过sql从这个库把数据放到另一个库

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧