意外发现的大批量导入数据SqlBulkCopy类
因为要做一个号码归属地查询小功能,因为要导入外部(文本文件)的电话归属地数据,使用的是SqlDataAdapter类,数据不多,只四万有多条,表也只有一个,phoneBook表,使用的是DataTable和SqlDataAdapter,测试了三次导入,平均18秒,但是我觉得太慢了,就百度了下【SQL Server批量导入数据】,发现了SqlBulkCopy这个神器,一秒内导入。
SqlBulkCopy 这个类用于数据库大批量的数据传递,通常用于新旧数据库之间的更新。关键的一点是,即使表结构不同,也可以通过表字段或者字段位置建立映射关系,将所需的数据导入到目标数据库。
下面代码测试了数据量为一百万条数据,几次测试耗时8秒左右。
/// <summary>
/// SqlBulkCopy类的使用,批量更新数据
/// </summary>
public static void SqlBulkCopyDemo()
{
String connStr = ConfigurationManager.ConnectionStrings["connStr"].ToString();
//从数据库中获得表结构和数据
DataTable student = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter("select * from student", connStr);
adapter.Fill(student);
//向表中添加数据
DataRow dr;
Random r = new Random();
Stopwatch st = new Stopwatch();
for(int i = 0; i<1000000; i++)//一百万条数据
{//数据表中的列:name,no,age,sex
dr = student.NewRow();
dr[0] = "小花" + i;
dr[1] = 108 + i;
dr[2] = r.Next(9, 40);//这里是因为数据表中有约束,
dr[3] = (i % 2 == 0 ? "男" : "女");//这个也是有约束
student.Rows.Add(dr);
}
SqlBulkCopy bulk = new SqlBulkCopy(connStr);
bulk.DestinationTableName = "student";//设置目标表,这里是数据库中的student表
bulk.ColumnMappings.Add(0, 0);//建立映射关系
bulk.ColumnMappings.Add(1, 1);
bulk.ColumnMappings.Add(2, 2);
bulk.ColumnMappings.Add(3, 3);
st.Start();//开始计时
bulk.WriteToServer(student.GetChanges());
st.Stop();//结束计时
Console.WriteLine("数据插入成功,耗时为:" + st.ElapsedMilliseconds + "毫秒");
}
测试了三次,结果如下:
1、SqlBulkCopy类的构造方法
其中: conn表示一个SqlConnection对象
connStr表示数据库连接字符串
- SqlBulkCopy(conn)
- SqlBulkCopy(connStr)
- SqlBulkCopy(connStr, SqlBulkCopyOptions copyOptions)
- SqlBulkCopy(conn, SqlBulkCopyOptions copyOptions, SqlTransaction externalTransaction)
其中还有几个陌生的对象:SqlBulkCopyOptions 和 SqlTransaction
1.1、SqlBulkCopyOptions类
这个类是一个枚举类型:
对象 | 值 | 备注 |
Default | 0 | |
KeepIdentity | 1 | 保留源标识值。 如果未指定,则由目标分配标识值。 |
CheckConstraints | 2 | 在插入数据的同时检查约束。 默认情况下,不检查约束。 |
TableLock | 4 | 在批量复制操作期间获取批量更新锁。 如果未指定,则使用行锁。 |
KeepNulls | 8 | 保留目标表中的空值,而不管默认值的设置如何。 如果未指定,则空值将由默认值替换(如果适用) |
FireTriggers | 16 | 指定后,会导致服务器为插入到数据库中的行激发插入触发器。 |
UseInternalTransaction | 32 |
如果已指定,则每一批批量复制操作将在事务中进行。 如果指示了此选项,并且为构造函数提供了 System.Data.SqlClient.SqlTransaction对象,则发生 System.ArgumentException(参数异常)。因为两个事务冲突了。 |
1.2、SqlTransaction类
这个类是事务类,是个密封类,实现了DbTransaction抽象类
2、SqlBulkCopy类的常用属性
属性名 | 功能 | 备注 |
BatchSize | 设置或获取每达到多少行就更新到服务器(也就是目标表) | 值为int, |
BulkCopyTimeout | 设置或获取超时时间 | 默认30秒,如果设置成0,将无限制等待, 值为int,单位为秒 |
DestinationTableName | 设置或获取服务器上的目标表的名称 | 也就是批量更新的目标表, 值为String类型 |
EnableStreaming | 设置或获取是否支持传输 IDataReader 对象的数据 | true为支持, 值为bool类型 |
NotifyAfter | 设置或获取在生成通知事件之前要处理的行数 | 默认为0, 值为int类型, |
ColumnMappings | 获取列映射定义数据源中的列和目标表中的列之间的映射关系 | 返回值为SqlBulkCopyColumnMappingCollection |
2.1、表中的SqlBulkCopyColumnMappingCollection类型是一个映射集合类,是目标表的列和源表的列的映射关系的集合。
这个类是一个密封类,不能被继承,实现了一个CollectionBase抽象类。
SqlBulkCopyColumnMappingCollection没有提供构造方法,我们也不需要去newat的对象,主要是使用它的几个重载的Add()方法
Add()有五个重载的方法:
- SqlBulkCopyColumnMapping Add(SqlBulkCopyColumnMapping bulkCopyColumnMapping);
- SqlBulkCopyColumnMapping Add(string sourceColumn, string destinationColumn);
- SqlBulkCopyColumnMapping Add(int sourceColumnIndex, string destinationColumn);
- SqlBulkCopyColumnMapping Add(string sourceColumn, int destinationColumnIndex);
- SqlBulkCopyColumnMapping Add(int sourceColumnIndex, int destinationColumnIndex);
其中四个方法是类似的,都是对应的列名或者列的位置。
第一个方法是添加一个已经构建好的SqlBulkCopyColumnMapping对象,
他也有集合常用的方法:
方法名 | 功能 | 备注 |
Clear(); | 清除集合中的映射关系 | |
Contains(SqlBulkCopyColumnMapping value); | 判断是否包含指定映射关系 | |
IndexOf(SqlBulkCopyColumnMapping value); | 返回指定映射关系的位置 | |
Remove(SqlBulkCopyColumnMapping value); | 移除指定映射关系 | |
RemoveAt(int index); | 移除指定位置的映射关系 | |
Insert(int index, SqlBulkCopyColumnMapping value); | 在指定位置插入映射关系 | |
CopyTo(SqlBulkCopyColumnMapping[] array, int index); | 从指定位置开始将映射关系复制到指定数组中 | index指定的集合中的位置, 而不是数组中的角标 |
3、SqlBulkCopy类的常用方法
- WriteToServer,这个方法重载了四次,功能是将数据写到目的表中。
WriteToServer(DataRow[] rows); | 将 DataRow 数组所有元素写到目标表中 |
WriteToServer(DataTable table); | 将 DataTable 所有行写到目标表中 |
WriteToServer(IDataReader reader); | 将指定的 IDataReader 对象中的数据写到目标表中 |
WriteToServer(DataTable table, DataRowState rowState); | 将 DataTable 中指定状态的所有行写到目标表中 |
【上表中的 DataRowState 状态行可以参考这篇博客DataTable的AcceptChanges()方法和DataRow的RowState属性】
这个类还提供了八个异步写的方法,我还没全部理解,就不放上来了。
既然能够有写的操作,那这个类应该类似于流,它还有一个Close()方法,用于关闭 SqlBulkCopy 实例。
意外发现的大批量导入数据SqlBulkCopy类的更多相关文章
- 大批量导入数据的SqlBulkCopy类
SqlBulkCopy 这个类用于数据库大批量的数据传递,通常用于新旧数据库之间的更新.关键的一点是,即使表结构不同,也可以通过表字段或者字段位置建立映射关系,将所需的数据导入到目标数据库. 下面代 ...
- IBatis.Net 下使用SqlBulkCopy 大批量导入数据 问题解决
SQLBulkCopy是继承SQLClient空间下的一个特殊类,它可以帮助我们以映射的方式把DataTable和DataReader数据大批量导入到数据库对应表中 public void Inert ...
- Java不写文件,LOAD DATA LOCAL INFILE大批量导入数据到MySQL的实现(转)
MySQL使用load data local infile 从文件中导入数据比insert语句要快,MySQL文档上说要快20倍左右.但是这个方法有个缺点,就是导入数据之前,必须要有文件,也就是说从文 ...
- Excel大批量导入数据到SQLServer数据库-万条只用1秒
private string ExcelToStudent() { /*---*/ var preStr = DateTime.Now.ToString("yyyyMMddHHmmssfff ...
- 读取接口XML和批量导入数据SqlBulkCopy
首先是C#处理xml文档 string urlStr = string.Format("http://……?timeBeg={0}&timeEnd={1}", timeBe ...
- C#中大批量导入数据SqlBulkCopy
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 使用BCP批量导入数据
本文原创,转载请标明出处 BCP 工具的使用 The bulk copy program utility (bcp) bulk copies data between an instance of M ...
- SqlLite用SQLiteTransaction快速导入数据
mysql与sql server都有整表导入的类库,但是查遍了资料发现sqlLite没有,除非自己去写个,发现用SQLiteTransaction导入数据也很快,附上代码 /// <summar ...
- C# SqlBulkCopy类批量导入数据
特别注意 sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...
随机推荐
- js-面试题1
//1. y 和 z的值? ; ; ; function add(n){n=n+;} y = add(x); function add(n){n=n+;} z = add(x); //y,z输出und ...
- loadrunner解决浏览器死机问题
初次接触loadrunner时,遇到很多问题.浏览器崩溃以及录不到脚本就折磨了一周时间.最后终于解决 一.浏览器崩溃问题 1.退出安全卫士和防火墙 2.去掉IE第三方扩展.工具-Internet选项- ...
- phpcmsV9于基本介绍
1.phpcms做企业站 2.内容+管理栏目=页面显示的导航 3.文件目录结构 根目录 api 接口文件目录 caches 缓存文件目录 confings 系统配置文件目录 caches_*系统缓存目 ...
- 一个web应用的诞生(6)--用户账户
之前登录注册的功能都已经完成,但是登录成功回到首页发现还是白茫茫的一片,对的,title一直都写得博客,那么最终目的也是写出一个轻博客来,但是,在发表文章之前是不是要先记录一下登录状态呢? 用户登录 ...
- PPT中翻书动画的制作
一.新建一个空白的PowerPoint文档. 二.制作两个页面: 1.点击“自选图形”右边的小三角,选择“基本图形”下的“折角形”图形,在PowerPoint中画出一个书页样的图形,宽度最好小 ...
- 关于jquery中封装函数如何传递当前元素的问题
需要对页面上一组元素进行ajax操作 <div id="aid"></div> <div id="aid"></div ...
- CSS3弹性盒模型新版和老版写法差异
1.在使用弹性盒模型的时候父元素必须要加display:box 或 display:inline-box: 新版弹性盒模型:flex:display : flex 老版弹性盒模型:box : disp ...
- 用js写出光棒效应的两种方法与jquery的两中方法
<script src="js/jQuery1.11.1.js" type="text/javascript"></script> &l ...
- Mr.聂 带你成为web开发大牛——入门篇(上)
作为一名IT届的后生,当初也经历过懵懂无知的实习期,对那种无力感深有体会.在这,希望能用我这几年的开发经验,让各位即将踏入或者刚刚踏入web开发领域的新人们少走些弯路.鉴于这是入门篇,下面我就从零为大 ...
- 前端面试题总结:HTML5,JS,CSS3,兼容性。
1. 请写出至少20个HTML5标签 <article><aside> <audio><video> <canvas><datalis ...