视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
SqlBulkCopy快速插入数据到SqlServer数据库
2020-11-09 15:36:20 责编:小采
文档


向SQL Server中导入大量数量可以用bulk insert,但是必须要求 插入 的文件在 数据 库机器上或者一个 数据 库可以访问的共享文件夹中(我不知道怎么设置共享文件夹,以使得SQL Server能访问到) SqlBulkCopy 是.net中的一个类,提供了导入大量 数据 的功能。

向SQL Server中导入大量数量可以用bulk insert,但是必须要求插入的文件在数据库机器上或者一个数据库可以访问的共享文件夹中(我不知道怎么设置共享文件夹,以使得SQL Server能访问到)

SqlBulkCopy 是.net中的一个类,提供了导入大量数据的功能。

基本用法如下:

using (SqlBulkCopy bc = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction, null))
{
 bc.BulkCopyTimeout = 10 * 60;
 bc.BatchSize = 10000;
 bc.DestinationTableName = "dbo.Destination";
 bc.WriteToServer(reader); //reader 是一个继承自IDataReader的类的实例
}

自己可以写代码来实现继承自IDataReader的类。有n多成员要实现。。

比如FieldCount, Read(), GetValue(int i), Close()等

下面是一个读文件的例子:

//返回记录的列数
 public int FieldCount 
 {
 get { return 3; }
 }

 //读记录,此方法会被自动调用
 public bool Read()
 {
 if (_Reader == null)
 _Reader = new StreamReader(_FilePath);

 string line = _Reader.ReadLine();
 
 if (line != null)
 {
 _CurrentQueryItem = GetRawData(line);
 _Count++;

 while (_CurrentQueryItem == null)//如果读出的是不满足条件的记录,则读下一条记录
 {
 Read();
 }
 return true;
 } 
 return false;
 }

 //返回一条记录中第i 列(项)的值,此方法会被自动调用
 //SqlBulkCopy内部应该有一个循环,从0到FieldCount -1 ,再调用GetValue(int i)这个方法。我猜的。。
 public object GetValue(int i)
 {
 if (_CurrentQueryItem == null)
 return null;

 switch (i)
 {
 //如果数据库中表的第一列是自增字段,则会忽略第一列,也就是说此方法被调用时,i只会从1开始,所以不需要case 0的情况。估计.net内部去取目的表的schema,自动判断哪些列是需要从外部导入的。有空再研究这个问题
 case 0:
 return _CurrentQueryItem.Item1;
 case 1:
 return _CurrentQueryItem.Item2;
 case 2:
 return _CurrentQueryItem.Item3;
 default:
 throw new IndexOutOfRangeException();
 }
 }

 //释放资源
 public void Close()
 {
 Dispose();
 }

 public void Dispose()
 {
 if (_Reader != null)
 _Reader.Close();
 }

有一些其他属性其方法需要自己实现,当然有的不实现也没关系。似乎重要的就以上几个方法了。
对照SqlDataRead,自己可以猜想出会用到哪些方法。

经过实验,一个文件如果一行一行插入到数据库里,需要大约2分钟,如果用SqlBulkCopy 10秒左右就完成了。而且可以自己实现类来指定处理什么数据,也不用把文件放在数据库机器上了。不错。

忘说了,SqlBulkCopy里用到的connction对象只能是SqlConnection。SqlBulkCopy.WriteToServer (DataRow]) 和SqlBulkCopy.WriteToServer (DataTable) 都是可以的。

下载本文
显示全文
专题