VB .NET - Usando o novo recurso Bulk Copy


Um dos novos recursos da ADO.NET 2.0 é o objeto SqlBulkCopy. Esta classe procurar fornecer funcionalidade similar ao utilitário de linha de comando do Microsoft SQL Server conhecido como bcp. O bcp basicamente era usado para efetuar a cópia de grande volume de dados entre duas base de dados SQL Server.

O SqlBulkcopy vai além, pois permite ser usado também entre DataSets, DataTables , Arrays de objetos DataRow , DataReader, etc. e não somente entre base de dados SQL Server.

A seguir, a título de ilustração, temos os passos que devem ser seguidos para efetuar a inclusão de linhas de um DataReader em um fonte de dados existente usando o SqlBulkCopy:

  1. Criar uma conexão e um objeto Command para a fonte de dados
  2. Aplicar o método Command.ExecuteReader para criar o DataReader
  3. Criar um novo objeto SqlBulkCopy com a string de conexão usando o membro apropriado da enumeração do SqlBulkCopy
  4. Definir o valor da propriedade : SqlBulkCopy.DestinationTableName
  5. Definir outras propriedades opcionais do SqlBulkCopy como BatchSize e BulkCopyTimeout
  6. Invocar o método SqlBulkCopy.WriteToServer para realizar a operação de cópia
  7. Aplicar o método SqlBulkCopy.Close() e em seguida fechar a conexão.

A tabela abaixo descreve os membros da enumeração do SqlBulkCopyOptions:

Membro Descrição
ChecConstraints Aplica a verificação de restrições durante o processo de cópia
Default Não usa opções para a operação de cópia em massa
FireTriggers Permite triggers INSERT serem disparados durante a processo de cópia
KeepIdentity Usa valores Identity da tabela fonte ao invés de gerar novos valores de identity baseados na semente da tabela de destino.
KeepNulls Retêm valores fontes null
TableLock Aplica um lock na tabela para a duração do processo de cópia. O padrão é o lock de linhas.
UseInternalTransaction Faz com que cada lote de sql bulkcopy seja executado dentro de uma transação

Vejamos um exemplo de código bem simples que realiza a cópia da tabela Employees para a tabela EmployeesCopia no banco de dados Northwind. Estamos obtendo a string de conexão , criando a conexão para em seguida obter os dados da tabela origem.

Criamos uma nova conexão na qual será criado o objeto SqlBulkCopy e definida a tabela de destino. Finalmente o método WriteToServer efetiva a operação de cópia.


Dim connectionString As String = ConfigurationManager.ConnectionStrings("Northwind").ConnectionString 
Dim conexao As SqlConnection = New SqlConnection(connectionString) 
Dim comando As SqlCommand = New SqlCommand("SELECT * FROM Employees", conexao ) 

conexao.Open 

Dim dr As SqlDataReader = comando.ExecuteReader 
Dim novaConexao As SqlConnection = New SqlConnection(connectionString) 

novaConexao.Open 

Dim bulk As SqlBulkCopy = New SqlBulkCopy(novaConexao) 
bulk.DestinationTableName = "EmployeesCopia" 
bulk.WriteToServer(dr) 

novaConexao.Close 
dr.Close 

conexao.Close 
bulk.Close

Você deve estar se perguntando: "Por que eu não uso uma stored procedure com a instrução INSERT INTO ou SELECT INTO na tabela de destino, isto seria apenas 1 linha de código ?"

O desempenho meu amigo , o desempenho.O SqlBulkCopy realiza a operação de cópia de volume grande de dados muito mais rápido (na maioria das vezes...).

Mas por que ele é tão rápido ?  Alguns dos motivos são:

1- Ao efetuar múltiplos INSERTS sem o SqlBulkCopy, cada Insert é uma instrução em si mesma. Com Bulk Copy , não existe este custo de executar uma instrução para cada linha.
2- Usando Bulk Copy não existe o múltiplo ida-e-volta na rede; as linhas são enviadas do cliente para o servidor de forma contínua.
3- O mecanismo de armazenamento do servidor pode efetuar um otimização das linhas inseridas quando a operação de cópia usa o SqlBulkCopy.

Para encerrar vamos criar um projeto para mostrar um exemplo prático de utilização deste novo recurso. Os resultados serão mais efetivos para grande volume de dados.

Crie um novo projeto no VB 2005 Express Edition com o nome de bcpNet. No formulário form1.vb inclua um botão de comando e a seguir inclua o seguinte código no formulário:

Imports System.Data.sqlclient

Public Class Form1

Dim connectionstring = "Data Source=.\SQLEXPRESS;AttachDbFilename='D:\Documents and Settings\Macoratti.MACORATI\Meus documentos\Cadastro.mdf';
Integrated Security=True;Connect Timeout=30;User Instance=True"

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

Dim origem As SqlConnection = New SqlConnection(connectionstring)
Dim destino As SqlConnection = New SqlConnection(connectionstring)

Dim cmd As SqlCommand = New SqlCommand("DELETE FROM ProdutosCopia", destino)

Try

   origem.Open()
   destino.Open()

   cmd.ExecuteNonQuery()

   cmd = New SqlCommand("SELECT * FROM Produtos", origem)

   Dim reader As SqlDataReader = cmd.ExecuteReader
   Dim bulkData As SqlBulkCopy = New SqlBulkCopy(destino)

   bulkData.DestinationTableName = "ProdutosCopia"
   bulkData.WriteToServer(reader)

   bulkData.Close()

Catch ex As Exception
   MsgBox(ex.Message)

Finally

destino.Close()
origem.Close()

End Try

End Sub
End
Class

O código acima efetua a cópia da tabela Produtos da base de dados Cadastro.mdf para a tabela ProdutosCopia usando o SqlBulkCopy.

Bom estudo e até o próximo artigo VB.NET...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti