Operação únicas de cópia em massa

Baixar ADO.NET

A abordagem mais simples para a execução de 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 a oportunidade de disponibilizá-la de volta.

Observação

Se você precisar reverter toda ou parte da cópia em massa quando ocorrer um erro, poderá usar uma transação gerenciada SqlBulkCopy 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 for inscrita (implícita ou explicitamente) em uma transação de System.Transactions.

Para obter mais informações, veja Operações de cópia em massa e transação.

As etapas gerais para executar uma operação de cópia em massa são:

  1. Conectar-se ao servidor de origem e obter os dados a serem copiados. Os dados também podem vir de outras fontes, desde que possam ser recuperados de um objeto IDataReader ou DataTable.

  2. Conecte-se ao servidor de destino (a menos que você queira que SqlBulkCopy estabeleça uma conexão para você).

  3. Crie um objeto SqlBulkCopy, configurando as propriedades necessárias.

  4. Defina a propriedade DestinationTableName para indicar a tabela de destino para a operação BULK INSERT.

  5. Chame um dos métodos WriteToServer.

  6. Opcionalmente, atualize as propriedades e chame WriteToServer novamente, conforme necessário.

  7. Chame Close ou encapsule as operações de cópia em massa em uma instrução Using.

Cuidado

É recomendável que os tipos de dados da coluna de origem e destino correspondam. Se os tipos de dados não corresponderem, o SqlBulkCopy tentará converter cada valor de origem para o tipo de dados de destino usando as regras empregadas por Value. As conversões podem afetar o desempenho e também podem resultar em erros inesperados. Por exemplo, um tipo de dados Double pode ser convertido em um tipo de dados Decimal na maior parte das vezes, mas não sempre.

Exemplo

O aplicativo de console a seguir demonstra como carregar dados usando a classe SqlBulkCopy. Neste exemplo, um SqlDataReader é usado para copiar dados da tabela Production.Product no banco de dados AdventureWorks do SQL Server em uma tabela semelhante no mesmo banco de dados.

Importante

Essa amostra não será executada, a menos que você tenha criado as tabelas de trabalho conforme descrito em Configuração de exemplo de cópia em massa. Esse código é fornecido para demonstrar a sintaxe para usar somente SqlBulkCopy. Se as tabelas de origem e destino estiverem localizadas na mesma instância do SQL Server, será mais fácil e mais rápido usar uma instrução INSERT … SELECT do Transact-SQL para copiar os dados.

using Microsoft.Data.SqlClient;

class Program
{
    static void Main()
    {
        string connectionString = GetConnectionString();
        // Open a sourceConnection to the AdventureWorks database.
        using (SqlConnection sourceConnection =
                   new SqlConnection(connectionString))
        {
            sourceConnection.Open();

            // Perform an initial count on the destination table.
            SqlCommand commandRowCount = new SqlCommand(
                "SELECT COUNT(*) FROM " +
                "dbo.BulkCopyDemoMatchingColumns;",
                sourceConnection);
            long countStart = System.Convert.ToInt32(
                commandRowCount.ExecuteScalar());
            Console.WriteLine("Starting row count = {0}", countStart);

            // Get data from the source table as a SqlDataReader.
            SqlCommand commandSourceData = new SqlCommand(
                "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 SqlConnection(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 SqlBulkCopy(destinationConnection))
                {
                    bulkCopy.DestinationTableName =
                        "dbo.BulkCopyDemoMatchingColumns";

                    try
                    {
                        // Write from the source to the destination.
                        bulkCopy.WriteToServer(reader);
                        // Print the number of rows processed using the 
                        // RowsCopied property.
                        Console.WriteLine("{0} rows were processed.",
                            bulkCopy.RowsCopied);
                    }
                    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 = 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();
            }
        }
    }

    private static string GetConnectionString()
    // To avoid storing the sourceConnection string in your code, 
    // you can retrieve it from a configuration file. 
    {
        return "Data Source=(local); " +
            " Integrated Security=true;" +
            "Initial Catalog=AdventureWorks;";
    }
}

Realizando uma operação de cópia em massa usando o Transact-SQL e a o comando class

O exemplo a seguir ilustra como usar o método ExecuteNonQuery para executar a instrução BULK INSERT.

Observação

O caminho do arquivo da 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 (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();  
}  

Próximas etapas