SqlBulkCopy类数据导入
在ASP.NET 2.0中提供了一个新的类SqlBulkCopy类,它在性能上的优势更超过了上面的方法,它可以通过让DataSet或是DataReader中大量的数据通过数据流直接进行装载,然后可以将这些记录添加到指定的数据表中。
SqlBulkCopy类只有在SQL Server的表中写入数据,但在使用其它的数据库时,可以通过数据源来使用,SqlBulkCopy类主要包括一个实例方法WriteToServer,它用来把数据从一个数据源传输到另外一个数据源。WriteToServer的方法可以快速的写入DataRow数组数据,DataTable和DataReader。在实际开发的过程中,可以视情况而定,选择我们所喜欢的方法,我们看它使用的方法: WriteToServer(DataTable)写入数据表 WriteToServer(DataRow)批次写入数据行
WriteToServer(DataTable,DataRowState)按行状态写入数据库表 WriteToServer(DataReader)写入DataReader对象
在多数情况下,我们选择最好的方法是DataReader对象,因为DataReader是一个读取只向前和只读流的方式,所以它要比DataTable和DataRows更快,我们现在来看看下面的代码,它用来把数据从一张表中传输到另一张表中。 代码清单:
string strConnection = ConfigurationManager.AppSettings[\].ToString();//读取Web.config文件中的数据库连接字符串
SqlConnection sourceconnection = new SqlConnection(strConnection);//数据的连接方式是SQL Server
sourceconnection.Open();//打开数据库连接
SqlCommand cmd = new SqlCommand(\);//通过命令来读取SQL语句
cmd.Connection = sourceconnection;//获取连接方式
SqlDataReader reader = cmd.ExecuteReader();//开始执和结果集,获取DataReader记录集 //连接目标数据库连接,并且打开数据库连接方式,在此由于调用同一个数据库,连接字符串没有变 SqlConnection destinationConnection = new SqlConnection(strConnection); destinationConnection.Open(); //调用SqlBulkCopy类的方法
SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection); //获取目标表的名称
bulkCopy.DestinationTableName = \; //写入DataReader对象
bulkCopy.WriteToServer(reader); //关闭各个对象 reader.Close();
sourceconnection.Close(); destinationConnection.Close();
上例中,我们使用的是SQL Server 2005的master数据库,我们在使用SqlBulkCopy的时候,需要了解一下它的几个重要的属性:
BatchSize:属性的整数值;或者如果未设置任何值,则为零。每一批次中的行数。在每一批次结束时,将该批次中的行发送到服务器。
BulkCopyTimeOu:超时之前操作完成所允许的秒数。如果操作超时,事务便不会提交,而且所有已复制的行都会从目标表中移除。
ColumnMappings:返回 SqlBulkCopyColumnMapping 项的集合。列映射定义数据源中的列和目标表中的列之间的关系。如果数据源和目标表具有相同的列数,并且数据源中每个源列的序号位置匹配相应目标列的序号位置,则无需 ColumnMappings 集合。但是如果列计数不同,或序号位置不一致,则必须使用 ColumnMappings,以确保将数据复制到正确的列中。 DestinationTableName:指定的目标表中。
NotifyAfter:属性的整数值,或者如果未设置该属性,则为零。定义在生成通知事件之前要处理的行数。
在ColumnMappings属性中,我们可以看到SqlBulkCopyColumnMapping 项,它主要是用来定义SqlBulkCopy实例的数据源中的列与该实例的目标表中的列之间的映射。
结合着上面SqlBulkCopy的属性我们再来看一个综合的例子,此例中我们使用DataTable: 在本例中,我先自己建立一个数据库SqlBulkCopySample,然后建立一个表TblOrder,它主要是用来把Northwind数据库中的Orders表数据全导进来,所以它的表结构基本上和Orders一样,它们以应的关系如下:
ID (OrderID): int
Name (ShipName): nvarchar(40) Address (ShipAddress): nvarchar(60) City (ShipCity): nvarchar(15)
然后在Northwind数据中创建一个存储过程,如下: CREATE PROCEDURE dbo.SelectOrders AS
SELECT OrderID, ShipName, ShipAddress, ShipCity FROM Orders
我们在页面中增加一个按钮的点击事件,当事件触发的时候,执行的代码如下: private void btnStart_Click(object sender, EventArgs e) {
String sourceConnectionString =\Security=True\;
String destinationConnectionString =\Catalog=SqlBulkCopySample;Integrated Security=True\;
DataTable data = SelectDataFromSource(sourceConnectionString);//获取数据 CopyDataToDestination(destinationConnectionString, data);//复制数据 }
获取数据非常简单,它只是通过执行存储过程返回一个DataTable的查询结果集,如下: private DataTable SelectDataFromSource(String connectionString) {
DataTable data = new DataTable();
using (SqlConnection connection = new SqlConnection(connectionString)) {
SqlCommand command = new SqlCommand(\, connection); command.CommandType = CommandType.StoredProcedure; connection.Open();
SqlDataReader reader = command.ExecuteReader(); data.Load(reader); }
return data; }
接着,就执行数据复制的操作,此部分的代码为核心的部分,首先我们通过创建四个
SqlBulkCopyColumnMapping对象,然后把两个数据库中的表之间的一一对应关系表述出来,然后设置好BatchSize及BulkCopyTimeout属性,然后返回 SqlBulkCopyColumnMapping 项的集合,接着定义好目标表的名称,以SqlRowsCopied事件处理程序,在定义在生成通知事件之前要处理的行数时,然后调用WriteToServer(DataTable) 方法写入数据表,结束数据的复制,如下: private void CopyDataToDestination(String connectionString, DataTable table) {
SqlBulkCopyColumnMapping mapping1 =new SqlBulkCopyColumnMapping(\, \); SqlBulkCopyColumnMapping mapping2 =new SqlBulkCopyColumnMapping(\, \);
SqlBulkCopyColumnMapping mapping3 =new SqlBulkCopyColumnMapping(\, \);
SqlBulkCopyColumnMapping mapping4 =new SqlBulkCopyColumnMapping(\, \); SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString); bulkCopy.BatchSize = 100; bulkCopy.BulkCopyTimeout = 5;
bulkCopy.ColumnMappings.Add(mapping1); bulkCopy.ColumnMappings.Add(mapping2); bulkCopy.ColumnMappings.Add(mapping3); bulkCopy.ColumnMappings.Add(mapping4); bulkCopy.DestinationTableName = \;
bulkCopy.SqlRowsCopied +=new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); bulkCopy.NotifyAfter = 200; bulkCopy.WriteToServer(table); }
在bulkCopy_SqlRowsCopied的处理中,我只简单的通过展现给用户一个友好的提示信息让你可以知道目前有多少行被复制成功。代码如下:
private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) {
MessageBox.Show(String.Format(\, e.RowsCopied.ToString())); }
这样,在平时的开发中,我们可以灵活的在ASP.NET中使用SqlBulkCopy帮助我们复制大量的数据之间的数据源和数据表,并改善应用程序的性能。
获取数据非常简单,它只是通过执行存储过程返回一个DataTable的查询结果集,如下: private DataTable SelectDataFromSource(String connectionString) {
DataTable data = new DataTable();
using (SqlConnection connection = new SqlConnection(connectionString)) {
SqlCommand command = new SqlCommand(\, connection); command.CommandType = CommandType.StoredProcedure; connection.Open();
SqlDataReader reader = command.ExecuteReader(); data.Load(reader); }
return data; }
接着,就执行数据复制的操作,此部分的代码为核心的部分,首先我们通过创建四个SqlBulkCopyColumnMapping对象,然后把两个数据库中的表之间的一一对应关系表述出来,
然后设置好BatchSize及BulkCopyTimeout属性,然后返回 SqlBulkCopyColumnMapping 项的集合,接着定义好目标表的名称,以SqlRowsCopied事件处理程序,在定义在生成通知事件之前要处理的行数时,然后调用WriteToServer(DataTable) 方法写入数据表,结束数据的复制,如下: private void CopyDataToDestination(String connectionString, DataTable table) {
SqlBulkCopyColumnMapping mapping1 =new SqlBulkCopyColumnMapping(\, \); SqlBulkCopyColumnMapping mapping2 =new SqlBulkCopyColumnMapping(\, \);
SqlBulkCopyColumnMapping mapping3 =new SqlBulkCopyColumnMapping(\, \);
SqlBulkCopyColumnMapping mapping4 =new SqlBulkCopyColumnMapping(\, \); SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString); bulkCopy.BatchSize = 100; bulkCopy.BulkCopyTimeout = 5;
bulkCopy.ColumnMappings.Add(mapping1); bulkCopy.ColumnMappings.Add(mapping2); bulkCopy.ColumnMappings.Add(mapping3); bulkCopy.ColumnMappings.Add(mapping4); bulkCopy.DestinationTableName = \;
bulkCopy.SqlRowsCopied +=new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); bulkCopy.NotifyAfter = 200; bulkCopy.WriteToServer(table); }
在bulkCopy_SqlRowsCopied的处理中,我只简单的通过展现给用户一个友好的提示信息让你可以知道目前有多少行被复制成功。代码如下:
private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) {
MessageBox.Show(String.Format(\, e.RowsCopied.ToString())); }
这样,在平时的开发中,我们可以灵活的在ASP.NET中使用SqlBulkCopy帮助我们复制大量的数据之间的数据源和数据表,并改善应用程序的性能
在不同数据源之间转移数据是一个常见的开发任务。如果你应用过SQL Server,就会熟悉bcp(批量复制)命令。
它允许你快速将大型文件批量复制到SQL Server表或视图中。在.NET Framework 1.1中,可以通过SqlCommand对象利用bcp,但.NET Framework 2.0中增加了SqlBulkCopy类来简化这个繁琐的过程。 SqlBulkCopy类
虽然你仍然可以使用t-splbcp命令,但SqlBulkCopy类具有很强的性能优势。你只能使用这个类往SQL Server表中写入数据,但可以使用任何数据源。唯一要注意的地方在于,数据源的内容必须能够加载到一个DataTable对象中。 在详细说明这个类的用法前,我们先简单概括这个类的功能:
单独批量复制操作,可将数据从一个数据源移动到SQL Server表中。 ? 也可执行多个批量复制操作。
? 在数据库事务中可执行批量复制操作。
?
MSDN提供更多关于SqlBulkCopy类的方法和属性的细节。其最重要的属性为Destination TableName,最重要的方法为WriteToServer。
DestinationTableName属性指定接受复制记录的表。由于它有一个由三部分组成的名称(database.owningschema.name),因此它遵循SQL Server语法。你可以用它的数据库和所有模式来限制表名称。
数据库通过在连接字符串中指定(通过Initial Catalog值)。另外,如果表名称使用一个下划线或任何其它特殊的字符,你必须使用方括号避免这类名称,如[database.owningschema.name]。
实际上由这个超载的WriteToServer方法执行批量复制。它接受DataTable、DataRow和IDataReader对象为复制数据源。你还可以用DataTable对象包含一个DataRowState值,指定仅复制匹配的行。
下一个Windows控制台应用程序说明从一个数据库表向另一个数据库表复制数据这种非常基本的操作。从它的Employees表往这个表的备份表Employees_bcp中复制数据时,它使用标准的SQL Server 2000 Northwind数据库。 ――――――――――――――――――――――――――――
查看列表A(列表B中为对应的VB.NET代码)。基本上,这段代码连接到数据库,并将所有值从Employees表读入SqlDataReader对象中。
设定目标表名称后,则使用SqlDataReader对象执行批量复制操作(它作为唯一的参数提交)。你可以检查服务器上的目标表,看数据是否被复制。