Поделиться через


Отдельные операции массового копирования (ADO.NET)

Самый простой способ выполнения операции массового копирования в SQL Server заключается в выполнении одной операции для базы данных. По умолчанию операция массового копирования выполняется как изолированная, без использования транзакции и без возможности отката.

ПримечаниеПримечание

Если в случае ошибки необходимо откатить все или часть массового копирования, можно либо воспользоваться транзакцией под управлением SqlBulkCopy, либо выполнить операцию массового копирования в рамках существующей транзакции.Объект SqlBulkCopy также будет работать с System.Transactions, если это соединение прикреплено (явно или неявно) к транзакции System.Transactions.

Дополнительные сведения см. в разделе Операции транзакций и массового копирования (ADO.NET).

Далее приведены общие шаги по выполнению операции массового копирования.

  1. Подключитесь к серверу-источнику и получите данные для копирования. Если данные можно получить из объекта IDataReader или DataTable, они также могут поступать из других источников.

  2. Подключитесь к целевому серверу (если только не требуется, чтобы объект SqlBulkCopy сам установил соединение).

  3. Создайте объект SqlBulkCopy, задав необходимые свойства.

  4. Задайте свойство DestinationTableName, чтобы указать целевую таблицу для операции массовой вставки.

  5. Вызовите один из методов WriteToServer.

  6. Кроме того, если это необходимо, можно обновить свойства и вызвать метод WriteToServer.

  7. Вызовите метод Close или заключите операции массового копирования в оболочку из инструкции Using.

Предупреждающее замечаниеВнимание

Рекомендуется, чтобы типы данных исходного и целевого столбца были одинаковыми.Если типы данных разные, объект SqlBulkCopy попытается преобразовать каждое исходное значение в целевой тип данных с использованием правил, применяемых методом Value.Преобразования могут ухудшать производительность, а также приводить к непредвиденным ошибкам.Например, в большинстве случаев тип данных Double можно преобразовать в тип данных Decimal, однако иногда это невозможно.

Пример

Следующее приложение командной строки демонстрирует, как загружать данные при помощи класса SqlBulkCopy. В этом примере объект SqlDataReader используется, чтобы скопировать данные из таблицы Production.Product в базе данных SQL Server 2005 AdventureWorks в такую же таблицу в этой же базе данных.

Важное примечаниеВажно

Этот образец не запустится до тех пор, пока не будут созданы рабочие таблицы, описанные в разделе Пример настройки массового копирования (ADO.NET).Данный код предназначен только для демонстрации синтаксиса использования SqlBulkCopy.Если исходная и целевая таблицы расположены в одном и том же экземпляре SQL Server, легче и быстрее использовать для копирования данных инструкцию INSERT … SELECT языка Transact-SQL.

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 SqlCommand = 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
        ' 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;"
    End Function
End Module
using System.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);
                    }
                    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;";
    }
}

Выполнение операции массового копирования при помощи Transact-SQL и класса команды

При использовании платформы .NET Framework 1.1 или более ранней версии (которая не поддерживает класс SqlBulkCopy) также можно выполнить инструкцию Transact-SQL BULK INSERT при помощи объекта SqlCommand. Отметим, что использование этого приема никак не связано с использованием возможностей по массовому копированию, предоставляемых поставщиком данных .NET Framework для SQL Server.

В следующем примере иллюстрируется, как применять метод ExecuteNonQuery для выполнения инструкции BULK INSERT.

ПримечаниеПримечание

Путь к файлу для источника данных указан относительно сервера.Чтобы операция массового копирования была успешной, процесс сервера должен иметь доступ к этому пути.

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();
}

См. также

Другие ресурсы

Операции массового копирования в SQL Server (ADO.NET)