在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用。 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据。 .NET 2.0有一个SqlBulkCopy类,它可以帮助你从不同的数据源复制数据到SQL SERVER数据库。 本文中我将示范SqlBulkCopy类的不同应用。

数据库设计:
这个数据库的设计还是蛮简单的,它基于Northwind数据库的Products表。另外我还在Northwind数据库中创建了3个表。 详情可以看一下下面的数据库关系图。

Products_Archive 和Products_Latest有与Products表相同的结构,而Products_TopSelling表则与它们不同。 稍后我将在本文解释Products_TopSelling表的用途。

Products_Archive表包含770,000行。 你不用管这些数据是如何得到的,你只需要考虑如何把所有这些数据复制到Products_Latest表里。

从Products_Archive表 复制数据到 Products_Latest表:
SqlBulkCopy 包含一个方法 WriteToServer,它用来从数据的源复制数据到数据的目的地。 WriteToServer方法可以处理的数据类型有DataRow[]数组,DataTable 和 DataReader。 你可以根据不同的情形使用不同的数据类型,但是更多时候选择DataReader是一个比较好的主意。 这是因为DataReader是一个只向前的、只读的数据流,它不会保存数据,所以要比DataTable 和 DataRows[]都要快。 下面的代码的作用是把数据从源表复制到目的表。

private static void PerformBulkCopy()
{
string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; // 源
using (SqlConnection sourceConnection = new SqlConnection(connectionString))
{
SqlCommand myCommand = new SqlCommand("SELECT * FROM Products_Archive", sourceConnection);
sourceConnection.Open();
SqlDataReader reader = myCommand.ExecuteReader(); // 目的
using (SqlConnection destinationConnection = new SqlConnection(connectionString))
{
// 打开连接
destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
{
bulkCopy.BatchSize = ;
bulkCopy.NotifyAfter = ;
bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
bulkCopy.DestinationTableName = "Products_Latest";
bulkCopy.WriteToServer(reader);
}
} reader.Close(); }
}

这里有一对需要提及的知识点。 首先,我使用DataReader来从数据库的表中读取数据。 Products_Latest是目的表,因为数据要从Products_Archive表复制到Products_Latest表。 bulkCopy对象提供了一个SqlRowCopied事件,在每次处理完NotifyAfter属性指定的行数时发生。 本例中的意思就是每处理完1000行就触发一次该事件,因为NotifyAfter被设置成了1000

 
BatchSize属性是非常重要的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行数,在每一批次结束时,就将该批次中的行发送到数据库。 我将BatchSize设置成了500,其意思就是reader每读出500行就将他们发送到数据库从而执行批量复制的操作。 BatchSize的默认值是“1”,其意思就是把每一行作为一个批次发送到数据库。
 
设置不同的BatchSize在性能上将给你带来不同的结果。 你应该根据你的需求进行测试,来决定BatchSize的大小。
在不同的映射表之间复制数据 在上面的例子中两个表具有相同的结构。 有时,你需要在具有不同结构的表之间复制数据。 假如你要从Products_Archive表中把所有的产品名称及其数量复制到Products_TopSelling表里。 这两个表有着不同的字段名,具体可以看一下上面的“数据库设计”一节下的。
private static void PerformBulkCopyDifferentSchema()
{
string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; DataTable sourceData = new DataTable(); // 源
using (SqlConnection sourceConnection = new SqlConnection(connectionString))
{
SqlCommand myCommand = new SqlCommand("SELECT TOP 5 * FROM Products_Archive", sourceConnection);
sourceConnection.Open();
SqlDataReader reader = myCommand.ExecuteReader(); // 目的
using (SqlConnection destinationConnection = new SqlConnection(connectionString))
{
// 打开连接
destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
{
bulkCopy.ColumnMappings.Add("ProductID", "ProductID");
bulkCopy.ColumnMappings.Add("ProductName", "Name");
bulkCopy.ColumnMappings.Add("QuantityPerUnit", "Quantity");
bulkCopy.DestinationTableName = "Products_TopSelling";
bulkCopy.WriteToServer(reader);
}
} reader.Close(); }
}
ColumnMappings集合用于映射源表和目的表之间的列。
从XML文件复制数据到数据库的表中 数据源并不局限于数据库的表,你也可以使用XML文件做数据源。 这里有一个非常简单的使用XML文件做数据源进行批量复制操作的例子。 (Products.xml)
<?xml version="1.0" encoding="utf-8" ?>
<Products>
<Product productID="1" productName="Chai" />
<Product productID="2" productName="Football" />
<Product productID="3" productName="Soap" />
<Product productID="4" productName="Green Tea" />
</Products>
private static void PerformBulkCopyXMLDataSource()
{
string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; DataSet ds = new DataSet();
DataTable sourceData = new DataTable();
ds.ReadXml(@"C:Products.xml"); sourceData = ds.Tables[]; // 目的
using (SqlConnection destinationConnection = new SqlConnection(connectionString))
{
// 打开连接
destinationConnection.Open(); using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString))
{
// 列映射
bulkCopy.ColumnMappings.Add("productID", "ProductID");
bulkCopy.ColumnMappings.Add("productName", "Name"); bulkCopy.DestinationTableName = "Products_TopSelling";
bulkCopy.WriteToServer(sourceData);
}
}
}

首先把XML文件读进DataTable,然后再使用SqlBulkCopy类的WriteToServer方法。 因为目的表示是Products_TopSelling,所以我们必须执行列映射。

结论
本文中我示范了如何使用.NET 2.0引入的SqlBulkCopy类。 SqlBulkCopy类可以非常简单的把数据从一个数据源复制到SQL SERVER数据库。

原文链接

用.net中的SqlBulkCopy类批量复制数据 (转载)的更多相关文章

  1. 使用asp.net 2.0中的SqlBulkCopy类批量复制数据

    介绍:在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用. 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据. ASP.NET 2.0有一个Sq ...

  2. C# 使用 SqlBulkCopy 类批量复制数据到数据库

    最近公司需要优化导入的问题,由于之前使用的方式是生成 Insert 语句插入数据库,数据量小的时候还行,但是随着发展数据量渐渐大了,之前的方法性能就跟不上了,于是发现了 SqlBulkCopy 这个类 ...

  3. C# 使用SqlBulkCopy类批量复制大数据

    用途说明: 前些日子,公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储.于是在网上进行查找,发现了一个比较好的解决方案,就是采用S ...

  4. C# SqlBulkCopy类批量导入数据

    特别注意  sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...

  5. 使用SqlBulkCopy类批量复制大数据

    using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using Syst ...

  6. SqlBulkCopy类进行大数据(一万条以上)插入测试

    好多天没写博客了,刚刚毕业一个多月! 关于上一篇博客中提到的,在进行批量数据插入数据库的时候可以通过给存储过程传递一个类型为Table的参数进行相关操作,在这个过程中本人没有进行效率的测试.后来查找发 ...

  7. SqlBulkCopy类进行大数据(10000万条以上)插入测试

    好多天没写博客了,刚刚毕业一个多月,在IT的路上真是迷茫啊! 关于上一篇博客中提到的,在进行批量数据插入数据库的时候可以通过给存储过程传递一个类型为Table的参数进行相关操作,在这个过程中本人没有进 ...

  8. 转:SqlBulkCopy类进行大数据(一万条以上)插入测试

    转自:https://www.cnblogs.com/LenLi/p/3903641.html 结合博主实例,自己测试了一下,把数据改为3万行更明显!! 关于上一篇博客中提到的,在进行批量数据插入数据 ...

  9. (转)SqlBulkCopy批量复制数据

    在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还是进行不同数据源之间的迁移,都不是很方便.而 在.Net2.0中,SQLClient命名空间下增加了几个新类帮助我们 ...

随机推荐

  1. redis中使用 check-and-set 操作实现乐观锁

    WATCH 命令可以为 Redis 事务提供 check-and-set (CAS)行为. 被 WATCH 的键会被监视,并会发觉这些键是否被改动过了. 如果有至少一个被监视的键在 EXEC 执行之前 ...

  2. MySQL 字符集问题及安全的更新操作

    一.字符集乱码 1.操作系统字符集 [root@mysql5 ~]# cat /etc/system-release /etc/sysconfig/i18n CentOS release 6.5 (F ...

  3. Golang 网络爬虫框架gocolly/colly 一

    Golang 网络爬虫框架gocolly/colly 一 gocolly是用go实现的网络爬虫框架,目前在github上具有3400+星,名列go版爬虫程序榜首.gocolly快速优雅,在单核上每秒可 ...

  4. Python 为何能坐稳 AI 时代头牌语言

    原文链接:https://mp.weixin.qq.com/s?__biz=MzI0ODcxODk5OA==&mid=2247487055&idx=2&sn=ca0fe8740 ...

  5. springBoot系列教程08:拦截器(Interceptor)的使用

    拦截器intercprot  和 过滤器 Filter 其实作用类似 在最开始接触java 使用struts2的时候,里面都是filter 后来springmvc时就用interceptor 没太在意 ...

  6. 让你彻底弄清offset

    很多初学者对于JavaScript中的offset.scroll.client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太多太杂,并且由于浏览器差异性,图示也不完全正确. 图一 不知道 ...

  7. Java异常的正确使用姿势

    最近在项目代码中,遇见异常滥用的情形,会带来什么样的后果呢? 1. 代码可读性变差,业务逻辑难以理解 异常流与业务状态流混在一起,无法从接口协议层面理解业务代码,只能深入到方法(Method)内部才能 ...

  8. hadoop+hive+spark搭建(一)

    1.准备三台虚拟机 2.hadoop+hive+spark+java软件包 传送门:Hadoop官网 Hive官网 Spark官网      一.修改主机名,hosts文件 主机名修改 hostnam ...

  9. PHP连接LDAP进行登录验证

    基于安全性考虑,准备把PHP做的自动化平台加入ldap登录验证,具体做法如下: 了解背景: LDAP 的全称是"轻量级目录访问协议(Lightweight Directory Access ...

  10. 关于ORM的浴室思考

    这是一个由EF群引发的随笔 平时在一个EF群摸鱼,日常问题可以归纳为以下几种: 这条sql用linq怎么写? EF可以调用我写的存储过程么? EF好慢啊一些复杂查询写起来好麻烦-- 为什么会有这些问题 ...