许多人都有一个疑问,那就是不知道该如何于前端应用程序中完成数据库之间的大量复制作业。在此我们要示范如何使用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

章立民研究室敬上