SqlBulkCopy提供了一种将数据复制到Sql Server数据库表中高性能的方法。SqlBulkCopy 包含一个方法 WriteToServer,它用来从数据的源复制数据到数据的目的地。 WriteToServer方法可以处理的数据类型有DataRow[]数组,DataTable 和 DataReader。 你可以根据不同的情形使用不同的数据类型。SqlBulkCopy其原理是采用了SQL Server的BCP协议进行数据的批量复制。
用法
1、将数据库中的表复制到另一个数据库中的表。
本例将Pubs数据库的stores表中的资料复制到Northwind数据库的store表中。这两个表结构相同。
using
System.Data;
using
System.Data.SqlClient;
using
System.Configuration;
///
<summary>
///
数据库中的表复制到另一个数据库中的表
///
</summary>
private
void
SqlBulkCopyMethod()
{
try
{
SqlConnection connetionPub
=
new
SqlConnection(ConfigurationManager.ConnectionStrings[
"
PubsDB
"
].ConnectionString);
using
(connetionPub)
{
SqlCommand commandPub
=
connetionPub.CreateCommand();
using
(commandPub)
{
commandPub.CommandText
=
"
select * from stores
"
;
commandPub.CommandType
=
System.Data.CommandType.Text;
connetionPub.Open();
SqlConnection connectionBulkCopy
=
new
SqlConnection(ConfigurationManager.ConnectionStrings[
"
NorthwindDB
"
].ConnectionString);
using
(connectionBulkCopy)
{
connectionBulkCopy.Open();
SqlDataReader dataReader
=
commandPub.ExecuteReader();
SqlBulkCopy bulkCopy
=
new
SqlBulkCopy(connectionBulkCopy);
using
(bulkCopy)
{
bulkCopy.DestinationTableName
=
"
store
"
;
bulkCopy.WriteToServer(dataReader);
}
}
}
}
}
catch
(Exception ex)
{
throw
ex;
}
}
2、将DataTable中的资料批量插入到数据库中。
using
System.Data;
using
System.Data.SqlClient;
using
System.Configuration;
///
<summary>
///
将表中资料批量插入到数据库
///
转自:
http://www.cnblogs.com/mrliuc/archive/2011/01/18/1938271.html
///
</summary>
///
<param name="connectionString"></param>
///
<param name="TableName"></param>
///
<param name="dt"></param>
private
void
SqlBulkCopyByDatatable(
string
connectionString,
string
TableName, DataTable dt)
{
using
(SqlConnection conn
=
new
SqlConnection(connectionString))
{
using
(SqlBulkCopy sqlbulkcopy
=
new
SqlBulkCopy(connectionString, SqlBulkCopyOptions.UseInternalTransaction))
{
try
{
sqlbulkcopy.DestinationTableName
=
TableName;
for
(
int
i
=
0
; i
<
dt.Columns.Count; i
++
)
{
sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName);
}
sqlbulkcopy.WriteToServer(dt);
}
catch
(System.Exception ex)
{
throw
ex;
}
}
}
}
在博客园中看到下边文章挺有用处,此处摘过来。原文:http://www.cnblogs.com/stalwart/archive/2011/01/07/1930207.html
1、从一个表 复制数据到另一个表
using
System.Data;
using
System.Data.SqlClient;
using
System.Configuration;
///
<summary>
///
从一个表复制到别一个表
///
</summary>
private
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
=
500
;
bulkCopy.NotifyAfter
=
1000
;
bulkCopy.SqlRowsCopied
+=
new
SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
bulkCopy.DestinationTableName
=
"
Products_Latest
"
;
bulkCopy.WriteToServer(reader);
}
}
reader.Close();
}
}
public
void
bulkCopy_SqlRowsCopied(
object
obj, SqlRowsCopiedEventArgs e)
{
//
执行事件处理方法
}
注意:
首先,我使用DataReader来从数据库的表中读取数据。 Products_Latest是目的表,因为数据要从Products_Archive表复制到Products_Latest表。 bulkCopy对象提供了一个SqlRowCopied事件,在每次处理完NotifyAfter属性指定的行数时发生。 本例中的意思就是每处理完1000行就触发一次该事件,因为NotifyAfter被设置成了1000。
BatchSize属性是非常重要的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行数,在每一批次结束时,就将该批次中的行发送到数据库。 我将BatchSize设置成了500,其意思就是reader每读出500行就将他们发送到数据库从而执行批量复制的操作。 BatchSize的默认值是“1”,其意思就是把每一行作为一个批次发送到数据库。设置不同的BatchSize在性能上将给你带来不同的结果。 你应该根据你的需求进行测试,来决定BatchSize的大小。
2、在不同的映射表之间复制数据
上面的例子中两个表具有相同的结构。 有时,你需要在具有不同结构的表之间复制数据。
///
<summary>
///
不同表之间复制数据
///
</summary>
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集合用于映射源表和目的表之间的列。
3、从XML文件复制数据到数据库的表中
数据源并不局限于数据库的表,你也可以使用XML文件做数据源。 这里有一个非常简单的使用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
>
///
<summary>
///
使用XML作为数据源
///
</summary>
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[
0
];
//
目的
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,所以我们必须执行列映射。