Operações de cópia em massa única
A abordagem mais simples para executar uma operação de cópia em massa do SQL Server é executar uma única operação em um banco de dados. Por padrão, uma operação de cópia em massa é executada como uma operação isolada: a operação de cópia ocorre de forma não transacionada, sem oportunidade de revertê-la.
Nota
Se precisar reverter toda ou parte da cópia em massa quando ocorrer um erro, você poderá usar uma SqlBulkCopytransação gerenciada ou executar a operação de cópia em massa dentro de uma transação existente. SqlBulkCopy também funcionará com System.Transactions se a conexão estiver inscrita (implícita ou explicitamente) em uma transação System.Transactions .
Para obter mais informações, consulte Transações e operações de cópia em massa.
As etapas gerais para executar uma operação de cópia em massa são as seguintes:
Conecte-se ao servidor de origem e obtenha os dados a serem copiados. Os dados também podem vir de outras fontes, se puderem ser recuperados de um IDataReader ou DataTable objeto.
Conecte-se ao servidor de destino (a menos que você queira que SqlBulkCopy estabeleça uma conexão para você).
Crie um SqlBulkCopy objeto, definindo as propriedades necessárias.
Defina a propriedade DestinationTableName para indicar a tabela de destino para a operação de inserção em massa.
Chame um dos métodos WriteToServer .
Opcionalmente, atualize as propriedades e chame WriteToServer novamente conforme necessário.
Chame Closeou envolva as operações de cópia em massa em uma
Using
instrução.
Atenção
Recomendamos que os tipos de dados da coluna de origem e de destino coincidam. Se os tipos de dados não corresponderem, SqlBulkCopy tentará converter cada valor de origem para o tipo de dados de destino, usando as regras empregadas pelo Value. As conversões podem afetar o desempenho e também podem resultar em erros inesperados. Por exemplo, um Double
tipo de dados pode ser convertido em um Decimal
tipo de dados na maioria das vezes, mas nem sempre.
Exemplo
O aplicativo de console a seguir demonstra como carregar dados usando a SqlBulkCopy classe. Neste exemplo, a SqlDataReader é usado para copiar dados da tabela Production.Product no banco de dados SQL Server AdventureWorks para uma tabela semelhante no mesmo banco de dados.
Importante
Este exemplo não será executado a menos que você tenha criado as tabelas de trabalho conforme descrito em Configuração de exemplo de cópia em massa. Este código é fornecido para demonstrar a sintaxe para usar SqlBulkCopy somente. Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, será mais fácil e rápido usar uma instrução Transact-SQL INSERT … SELECT
para copiar os dados.
static void Main()
{
var connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
new(connectionString))
{
sourceConnection.Open();
// Perform an initial count on the destination table.
SqlCommand commandRowCount = new(
"SELECT COUNT(*) FROM " +
"dbo.BulkCopyDemoMatchingColumns;",
sourceConnection);
long countStart = Convert.ToInt32(
commandRowCount.ExecuteScalar());
Console.WriteLine("Starting row count = {0}", countStart);
// Get data from the source table as a SqlDataReader.
SqlCommand commandSourceData = new(
"SELECT ProductID, Name, " +
"ProductNumber " +
"FROM Production.Product;", sourceConnection);
SqlDataReader reader =
commandSourceData.ExecuteReader();
// Open the destination connection. In the real world you would
// not use SqlBulkCopy to move data from one table to the other
// in the same database. This is for demonstration purposes only.
using (SqlConnection destinationConnection =
new(connectionString))
{
destinationConnection.Open();
// Set up the bulk copy object.
// Note that the column positions in the source
// data reader match the column positions in
// the destination table so there is no need to
// map columns.
using (SqlBulkCopy bulkCopy =
new(destinationConnection))
{
bulkCopy.DestinationTableName =
"dbo.BulkCopyDemoMatchingColumns";
try
{
// Write from the source to the destination.
bulkCopy.WriteToServer(reader);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// Close the SqlDataReader. The SqlBulkCopy
// object is automatically closed at the end
// of the using block.
reader.Close();
}
}
// Perform a final count on the destination
// table to see how many rows were added.
long countEnd = Convert.ToInt32(
commandRowCount.ExecuteScalar());
Console.WriteLine("Ending row count = {0}", countEnd);
Console.WriteLine("{0} rows were added.", countEnd - countStart);
Console.WriteLine("Press Enter to finish.");
Console.ReadLine();
}
}
}
Imports System.Data.SqlClient
Module Module1
Sub Main()
Dim connectionString As String = GetConnectionString()
' Open a connection to the AdventureWorks database.
Using sourceConnection As SqlConnection = _
New SqlConnection(connectionString)
sourceConnection.Open()
' Perform an initial count on the destination table.
Dim commandRowCount As New SqlCommand( _
"SELECT COUNT(*) FROM dbo.BulkCopyDemoMatchingColumns;", _
sourceConnection)
Dim countStart As Long = _
System.Convert.ToInt32(commandRowCount.ExecuteScalar())
Console.WriteLine("Starting row count = {0}", countStart)
' Get data from the source table as a SqlDataReader.
Dim commandSourceData As New SqlCommand( _
"SELECT ProductID, Name, ProductNumber " & _
"FROM Production.Product;", sourceConnection)
Dim reader As SqlDataReader = commandSourceData.ExecuteReader
' Open the destination connection. In the real world you would
' not use SqlBulkCopy to move data from one table to the other
' in the same database. This is for demonstration purposes only.
Using destinationConnection As SqlConnection = _
New SqlConnection(connectionString)
destinationConnection.Open()
' Set up the bulk copy object.
' The column positions in the source data reader
' match the column positions in the destination table,
' so there is no need to map columns.
Using bulkCopy As SqlBulkCopy = _
New SqlBulkCopy(destinationConnection)
bulkCopy.DestinationTableName = _
"dbo.BulkCopyDemoMatchingColumns"
Try
' Write from the source to the destination.
bulkCopy.WriteToServer(reader)
Catch ex As Exception
Console.WriteLine(ex.Message)
Finally
' Close the SqlDataReader. The SqlBulkCopy
' object is automatically closed at the end
' of the Using block.
reader.Close()
End Try
End Using
' Perform a final count on the destination table
' to see how many rows were added.
Dim countEnd As Long = _
System.Convert.ToInt32(commandRowCount.ExecuteScalar())
Console.WriteLine("Ending row count = {0}", countEnd)
Console.WriteLine("{0} rows were added.", countEnd - countStart)
Console.WriteLine("Press Enter to finish.")
Console.ReadLine()
End Using
End Using
End Sub
Private Function GetConnectionString() As String
Throw New NotImplementedException()
End Function
End Module
Executando uma operação de cópia em massa usando Transact-SQL e a classe de comando
O exemplo a seguir ilustra como usar o ExecuteNonQuery método para executar a instrução BULK INSERT.
Nota
O caminho do arquivo para a fonte de dados é relativo ao servidor. O processo do servidor deve ter acesso a esse caminho para que a operação de cópia em massa seja bem-sucedida.
Using connection As SqlConnection = New SqlConnection(connectionString)
Dim queryString As String = _
"BULK INSERT Northwind.dbo.[Order Details] FROM " & _
"'f:\mydata\data.tbl' WITH (FORMATFILE='f:\mydata\data.fmt' )"
connection.Open()
SqlCommand command = New SqlCommand(queryString, connection);
command.ExecuteNonQuery()
End Using
using (SqlConnection connection = New SqlConnection(connectionString))
{
string queryString = "BULK INSERT Northwind.dbo.[Order Details] " +
"FROM 'f:\mydata\data.tbl' " +
"WITH ( FORMATFILE='f:\mydata\data.fmt' )";
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
command.ExecuteNonQuery();
}