VIsual Basic 2005 - 如何使用 SqlBulkCopy 对象来执行大量复制作业

本文介绍如何使用 SqlBulkCopy 对象在 Access 和 SQL Server 数据库间高效批量复制数据。演示了从 Access 的 章立民工作室 表复制两万多条记录到 SQL Server 的 北风贸易 数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

许多人都有一个疑问,那就是不知道该如何于前端应用程序中完成数据库之间的大量复制作业。在此我们要示范如何使用 SqlBulkCopy 对象来完成大量复制作业,会将 Access 数据库「汇整.mdb」之「章立民工作室」的两万多笔数据记录全部复制到 SQL Server 之「北风贸易」数据库的「Bulk_Target_章立民工作室」数据表中。

 

兹将程序代码列示如下,请注意我们使用了两个连接对象,一个是 OleDbConnection 对象,用以连结至来源数据所在的 Access 数据库;一个是 SqlConnection 对象,用以连结至目标数据表所在的 SQL Server 数据库:

 

Option Strict On
Imports
System.Data.OleDb
Imports System.Data.SqlClient



Private Sub btnGoBulkCopy_Click(ByVal sender As System.Object, _
 
ByVal e As System.EventArgs) Handles btnGoBulkCopy.Click
 
Me.btnGoBulkCopy.Enabled = False

  ' 利用SqlConnectionStringBuilder 对象来构建连接至目标服务器的连接字符串。
  Dim sqlconStringBuilder As New SqlConnectionStringBuilder()
  sqlconStringBuilder.DataSource =
"(local)SQLExpress"
  sqlconStringBuilder.InitialCatalog = "北风贸易"
  sqlconStringBuilder.IntegratedSecurity = True

  ' 利用OleDbConnectionStringBuilder 对象来构建连接至来源数据库的连接字符串。
  Dim accessStringBuilder As New OleDbConnectionStringBuilder()
  accessStringBuilder.DataSource = _
   
"C:VB2005_IO_Data_SampleDatabase杂汇.mdb"
  accessStringBuilder.Provider = "Microsoft.Jet.OLEDB.4.0"

  Try
      ' 建立连结至来源Access 数据库的连接。
      Using con_access As New OleDbConnection(accessStringBuilder.ConnectionString)

       
  ' 开启连结至来源Access 数据库的连接。
          con_access.Open()

        
 ' 计算出来源数据表有多少笔数据记录。
          Dim cmdSourceRowCount As New OleDbCommand( _
           
"SELECT COUNT(*) FROM 章立民工作室;", con_access)

         
Me.ProgressBar1.Maximum = _
            System.Convert.ToInt32(cmdSourceRowCount.ExecuteScalar())

       
  ' 建立连结至目标SQL Server 数据库的连接。
          Using con_bulkcopy As New _
            SqlConnection(sqlconStringBuilder.ConnectionString)

           
  ' 开启连接至目标SQL Server 的连接。
              con_bulkcopy.Open()

            
 ' 计算出目标数据表在执行大量复制作业前有多少笔数据记录。
              Dim cmdRowCount As New SqlCommand( _
                    
"SELECT COUNT(*) FROM dbo.Bulk_Target_章立民工作室;", _
                con_bulkcopy)
             
Dim countStart As Long = _
                System.Convert.ToInt32(cmdRowCount.ExecuteScalar())
             
Me.lblRowsCountBeforeBulkCopy.Text = _
                "
目标数据表在大量复制前拥有的数据笔数= " & countStart.ToString

             
' 使用oledbDataReader 取得所要复制的来源数据。
              Dim cmdSourceData As OleDbCommand = _
                 
New OleDbCommand("SELECT * FROM 章立民工作室", con_access)

             
Using accessReader As OleDbDataReader = cmdSourceData.ExecuteReader

                 
' 建立一个SqlBulkCopy 对象以便执行大量复制作业。
                  '
由于来源数据表与目标数据表的所有字段彼此完全正常对应,
                  '
所以不需要去对应两者的字段。
                  Using bcp As SqlBulkCopy = New SqlBulkCopy(con_bulkcopy)

                     
AddHandler bcp.SqlRowsCopied, AddressOf OnSqlRowsCopied

                      bcp.BatchSize = 1000
                      bcp.BulkCopyTimeout = 60
                      bcp.NotifyAfter = 1000

                     
' 指定目标数据表的名称。
                      bcp.DestinationTableName = "dbo.Bulk_Target_章立民工作室"

                     
' 将来源数据写入目标数据表。
                      bcp.WriteToServer(accessReader)

                  
End Using
              End Using

              ' 最后再计算出大量复制了多少笔数据记录。
              Dim countEnd As Long = _
                System.Convert.ToInt32(cmdRowCount.ExecuteScalar())
             
Me.lblRowsCountAfterBulkCopy.Text = _
               
"本次大量复制的数据笔数= " & (countEnd - countStart).ToString

         
End Using
      End Using
      MessageBox.Show("已经完成了大量复制作业")
 
Catch ex As Exception
      MessageBox.Show(ex.Message)
 
End Try

  Me.btnGoBulkCopy.Enabled = True
End
 Sub

Private
 Sub OnSqlRowsCopied(ByVal sender As Object, _
     
ByVal args As SqlRowsCopiedEventArgs)
 
 ' 更新进度列。
  Me.ProgressBar1.Value = CInt(args.RowsCopied)
End Sub

章立民研究室敬上

期待更多精彩,敬请关注:

http://www.china-pub.com/static/jsj_zlm_060824.html

 

要避免在使用SqlBulkCopy插入数据时出现重复数据,可以考虑以下两种方法: 1. 在插入之前先检查是否存在重复数据,如果存在则不进行插入。可以通过在目标表中设置唯一性约束或者创建临时表并在其中进行检查来实现。 2. 在SqlBulkCopy的WriteToServer方法中使用SqlBulkCopyOptions中的KeepIdentity选项,以保留目标表中已有的自增长主键,从而避免插入重复的自增长主键。 以下是使用第一种方法的示例代码: ```csharp using System.Data.SqlClient; using System.Data; //创建一个DataTable对象,用于存储要插入的数据 DataTable dt = new DataTable(); //添加列 dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Age", typeof(int)); //添加数据 dt.Rows.Add("John", 25); dt.Rows.Add("Mike", 30); //创建连接对象 SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TestDB;Integrated Security=True;"); //打开连接 conn.Open(); //创建事务对象 SqlTransaction tran = conn.BeginTransaction(); try { //创建SqlBulkCopy对象 using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, tran)) { //设置目标表名 bulkCopy.DestinationTableName = "Person"; //设置列映射 bulkCopy.ColumnMappings.Add("Name", "Name"); bulkCopy.ColumnMappings.Add("Age", "Age"); //使用SqlBulkCopyOptions中的CheckConstraints选项检查唯一性约束 bulkCopy.WriteToServer(dt, SqlBulkCopyOptions.CheckConstraints); } //提交事务 tran.Commit(); } catch (Exception ex) { //回滚事务 tran.Rollback(); throw ex; } finally { //关闭连接 conn.Close(); } ``` 使用第二种方法时,只需要在SqlBulkCopy的构造函数中指定KeepIdentity选项即可: ```csharp using System.Data.SqlClient; using System.Data; //创建一个DataTable对象,用于存储要插入的数据 DataTable dt = new DataTable(); //添加列 dt.Columns.Add("Name", typeof(string)); dt.Columns.Add("Age", typeof(int)); //添加数据 dt.Rows.Add("John", 25); dt.Rows.Add("Mike", 30); //创建连接对象 SqlConnection conn = new SqlConnection("Data Source=.;Initial Catalog=TestDB;Integrated Security=True;"); //打开连接 conn.Open(); //创建事务对象 SqlTransaction tran = conn.BeginTransaction(); try { //创建SqlBulkCopy对象,并设置KeepIdentity选项 using (SqlBulkCopy bulkCopy = new SqlBulkCopy(conn, SqlBulkCopyOptions.KeepIdentity, tran)) { //设置目标表名 bulkCopy.DestinationTableName = "Person"; //设置列映射 bulkCopy.ColumnMappings.Add("Name", "Name"); bulkCopy.ColumnMappings.Add("Age", "Age"); bulkCopy.WriteToServer(dt); } //提交事务 tran.Commit(); } catch (Exception ex) { //回滚事务 tran.Rollback(); throw ex; } finally { //关闭连接 conn.Close(); } ``` 以上示例代码仅供参考,实际应用中需要根据具体情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值