共用方式為


單一大量複製作業

執行 SQL Server 大量複製作業最簡單的方式為執行對資料庫的單一作業。 根據預設,大量複製作業會做為隔離作業執行:該複製作業會以非交易的方式進行,且沒有機會復原。

注意

當錯誤發生時,如果您需要復原全部或部分大量複製,您可以使用 SqlBulkCopy 受管理的交易,或執行現有交易中的大量複製作業。 如果將連線 (以隱含或明確的方式) 登記到 System.Transactions 交易中,則 SqlBulkCopy 也會使用 System.Transactions

如需詳細資訊,請參閱交易和大量複製作業

執行大量複製作業的一般步驟如下:

  1. 連接到來源伺服器,並取得要複製的資料。 如果可以從 IDataReaderDataTable 物件中擷取資料,則資料也可來自其他來源。

  2. 連線至目的伺服器 (除非您要讓 SqlBulkCopy 建立連線)。

  3. 建立 SqlBulkCopy 物件,並設定任何必要的屬性。

  4. 設定 DestinationTableName 屬性,以表示用於大量插入作業的目標資料表。

  5. 呼叫其中一種 WriteToServer 方法。

  6. 視需要,選擇性地更新屬性,並重新呼叫 WriteToServer

  7. 呼叫 Close,或將大量複製作業包裝在 Using 陳述式內。

警告

我們建議來源和目標資料行的資料類型必須相符。 如果資料類型不相符,則 SqlBulkCopy 會嘗試使用 Value 所使用的規則,將每個來源值轉換為目標資料類型。 轉換可能會影響效能,並也可能會導致未預期的錯誤。 例如,Double 資料類型大多可以轉換成 Decimal 資料類型,但並非總是如此。

範例

下列主控台應用程式示範如何使用 SqlBulkCopy 類別載入資料。 在這個範例中,SqlDataReader 用於從 SQL Server AdventureWorks 資料庫的 Production.Product 資料表,將資料複製到同一資料庫中的類似資料表中。

重要

除非您已如大量複製範例設定中所述建立工作資料表,否則將不會執行此範例。 這個程式碼僅是為了示範使用 SqlBulkCopy 的語法而提供。 如果來源和目的地資料表位於相同的 SQL Server 執行個體,則使用 Transact-SQL INSERT … SELECT 陳述式來複製資料會更方便且快速。

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

使用 Transact-SQL 及命令類別來執行大量複製作業

以下範例將示範如何使用 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();
}

另請參閱