意外发现的大批量导入数据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); 插入的时候列的顺序可 ...
随机推荐
- 蓝桥网试题 java 基础练习 十六进制转八进制
- -------------------------------------------------------------------------------------------------- ...
- asp.net权限认证:OWIN实现OAuth 2.0 之授权码模式(Authorization Code)
asp.net权限认证系列 asp.net权限认证:Forms认证 asp.net权限认证:HTTP基本认证(http basic) asp.net权限认证:Windows认证 asp.net权限认证 ...
- IIS7出现“HTTP 错误 404.17 - Not Found 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。”错误-Windows-
Errore HTTP 404.2 - Not Found" IIS 7.5 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理 如果你用了安全狗,可能只看到404错误,请打开狗,资源 ...
- python2.6.6安装MySQL-python模块正确方法
Centos6.5 x64 系统python2.6.6安装MySQL-python模块 一.安装前准备 操作系统:centos6.5 x64 ·安装python和python开发工具 python p ...
- 20155304田宜楠2006-2007-2 《Java程序设计》第一周学习总结
20155304田宜楠2006-2007-2 <Java程序设计>第一周学习总结 教材学习内容总结 - 浏览教材,根据自己的理解每章提出一个问题 第一章 除了书上提到的开发工具还有什么适合 ...
- 强化学习读书笔记 - 02 - 多臂老O虎O机问题
# 强化学习读书笔记 - 02 - 多臂老O虎O机问题 学习笔记: [Reinforcement Learning: An Introduction, Richard S. Sutton and An ...
- shell 获取指定目录下文件名
有两个目录a.b,两个文件夹目录里有一些文件的文件名是一样,不过后缀名不同,我想把a文件夹下跟b文件夹里相同文件名的文件覆盖到b去,并删除b里同名而不同后缀的文件,文件很多 #!/bin/bas ...
- C#自动弹出窗口并定时自动关闭
最近做个小项目,用到一个小功能:后台线程定时查询数据库,不符合条件的记录弹出消息提醒(在窗口最前面),并且过几秒钟再自动关闭弹出的窗口. 所以从网上找来资料,如下: WinForm 下实现一个自动关闭 ...
- java之重定向与转发
昨天搞了一个问题,关于手机返回按钮的(Android机,ios没有返回键) 在每一步操作都要进过鉴权,如果鉴权不通过就需要跳转到指定jsp页面,再进行link:到app进行登录操作: 然后问题出现了, ...
- ERP库位分布看板(库位管理)
客户正在使用的看板管理,根据厂家需求,做的二次开发. 一:看板效果 二:客户需求 1.客户需求:XX是一家汽车零部件(胶管,硅胶管等)的生产厂家,因此对原料,半成品的有效期有严格的要求. 多次调研得知 ...