Sdílet prostřednictvím


Operace transakcí a hromadného kopírování

Operace hromadného kopírování lze provádět jako izolované operace nebo jako součást transakce s více kroky. Tato druhá možnost umožňuje provádět více než jednu operaci hromadného kopírování ve stejné transakci, stejně jako provádět jiné databázové operace (například vložení, aktualizace a odstranění), zatímco stále je možné potvrdit nebo vrátit zpět celou transakci.

Ve výchozím nastavení se operace hromadného kopírování provádí jako izolovaná operace. Operace hromadného kopírování probíhá bez transakce bez příležitosti k vrácení zpět. Pokud potřebujete vrátit zpět všechny hromadné kopie nebo jeho část, pokud dojde k chybě, můžete použít SqlBulkCopy-managed transakce, provést hromadnou kopírování operace v rámci existující transakce nebo být zařazeny do System.TransactionsTransaction.

Provádění neaktutované operace hromadného kopírování

Následující konzolová aplikace ukazuje, co se stane, když operace hromadného kopírování, která neprovádí transakce, dojde k chybě v rámci operace.

V příkladu zdrojová tabulka a cílová tabulka obsahují Identity sloupec s názvem ProductID. Kód nejprve připraví cílovou tabulku odstraněním všech řádků a následným vložením jednoho řádku, jehož IDproduktu je známo, že ve zdrojové tabulce existuje. Ve výchozím nastavení se v cílové tabulce pro každý přidaný řádek vygeneruje nová hodnota Identity sloupce. V tomto příkladu je při otevření připojení nastavena možnost, která vynutí proces hromadného načtení k použití Identity hodnot ze zdrojové tabulky.

Operace hromadného kopírování se provede s vlastností nastavenou BatchSize na 10. Když operace narazí na neplatný řádek, vyvolá se výjimka. V tomto prvním příkladu je operace hromadného kopírování neprovednutá. Všechny dávky zkopírované až do bodu chyby jsou potvrzeny; dávka obsahující duplicitní klíč se vrátí zpět a operace hromadného kopírování se zastaví před zpracováním jiných dávek.

Poznámka:

Tato ukázka se nespustí, pokud jste nevytvořili pracovní tabulky, jak je popsáno v příkladu hromadného kopírování. Tento kód je k dispozici k předvedení syntaxe pouze pro použití sqlBulkCopy . Pokud jsou zdrojové a cílové tabulky umístěny ve stejné instanci SQL Serveru, je jednodušší a rychlejší použít příkaz Jazyka Transact-SQLINSERT … SELECT ke kopírování dat.

var connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
           new(connectionString))
{
    sourceConnection.Open();

    //  Delete all from the destination table.
    SqlCommand commandDelete = new()
    {
        Connection = sourceConnection,
        CommandText =
        "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
    };
    commandDelete.ExecuteNonQuery();

    //  Add a single row that will result in duplicate key
    //  when all rows from source are bulk copied.
    //  Note that this technique will only be successful in
    //  illustrating the point if a row with ProductID = 446
    //  exists in the AdventureWorks Production.Products table.
    //  If you have made changes to the data in this table, change
    //  the SQL statement in the code to add a ProductID that
    //  does exist in your version of the Production.Products
    //  table. Choose any ProductID in the middle of the table
    //  (not first or last row) to best illustrate the result.
    SqlCommand commandInsert = new()
    {
        Connection = sourceConnection,
        CommandText =
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" +
        "INSERT INTO " + "dbo.BulkCopyDemoMatchingColumns " +
        "([ProductID], [Name] ,[ProductNumber]) " +
        "VALUES(446, 'Lock Nut 23','LN-3416');" +
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
    };
    commandInsert.ExecuteNonQuery();

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

    // Set up the bulk copy object using the KeepIdentity option.
    using (SqlBulkCopy bulkCopy = new(
               connectionString, SqlBulkCopyOptions.KeepIdentity))
    {
        bulkCopy.BatchSize = 10;
        bulkCopy.DestinationTableName =
            "dbo.BulkCopyDemoMatchingColumns";

        // Write from the source to the destination.
        // This should fail with a duplicate key error
        // after some of the batches have been copied.
        try
        {
            bulkCopy.WriteToServer(reader);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            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 sourceConnection to the AdventureWorks database.
        Using sourceConnection As SqlConnection = _
           New SqlConnection(connectionString)
            sourceConnection.Open()

            ' Delete all from the destination table.
            Dim commandDelete As New SqlCommand
            commandDelete.Connection = sourceConnection
            commandDelete.CommandText = _
               "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
            commandDelete.ExecuteNonQuery()

            ' Add a single row that will result in duplicate key
            ' when all rows from source are bulk copied.
            ' Note that this technique will only be successful in
            ' illustrating the point if a row with ProductID = 446
            ' exists in the AdventureWorks Production.Products table.
            ' If you have made changes to the data in this table, change
            ' the SQL statement in the code to add a ProductID that
            ' does exist in your version of the Production.Products
            ' table. Choose any ProductID in the middle of the table
            ' (not first or last row) to best illustrate the result.
            Dim commandInsert As New SqlCommand
            commandInsert.Connection = sourceConnection
            commandInsert.CommandText = _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" & _
               "INSERT INTO dbo.BulkCopyDemoMatchingColumns " & _
               "([ProductID], [Name] ,[ProductNumber]) " & _
               "VALUES(446, 'Lock Nut 23','LN-3416');" & _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
            commandInsert.ExecuteNonQuery()

            ' 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()

            ' Set up the bulk copy object using the KeepIdentity option.
            Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(connectionString, _
              SqlBulkCopyOptions.KeepIdentity)
                bulkCopy.BatchSize = 10
                bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns"

                ' Write from the source to the destination.
                ' This should fail with a duplicate key error
                ' after some of the batches have already been copied.
                Try
                    bulkCopy.WriteToServer(reader)

                Catch ex As Exception
                    Console.WriteLine(ex.Message)

                Finally
                    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 Sub

    Private Function GetConnectionString() As String
        Throw New NotImplementedException()
    End Function
End Module

Provedení vyhrazené operace hromadného kopírování v transakci

Ve výchozím nastavení je operace hromadného kopírování vlastní transakcí. Pokud chcete provést vyhrazenou operaci hromadného kopírování, vytvořte novou instanci SqlBulkCopy s připojovací řetězec nebo použijte existující SqlConnection objekt bez aktivní transakce. V každém scénáři operace hromadného kopírování vytvoří a pak potvrdí nebo vrátí transakce zpět.

V konstruktoru SqlBulkCopy třídy můžete explicitně zadat UseInternalTransaction možnost, která explicitně způsobí spuštění operace hromadného kopírování ve vlastní transakci, což způsobí, že každá dávka operace hromadného kopírování se provede v rámci samostatné transakce.

Poznámka:

Vzhledem k tomu, že různé dávky se provádějí v různých transakcích, pokud dojde k chybě během operace hromadného kopírování, všechny řádky v aktuální dávce budou vráceny zpět, ale řádky z předchozích dávek zůstanou v databázi.

Následující konzolová aplikace je podobná předchozímu příkladu s jednou výjimkou: V tomto příkladu operace hromadného kopírování spravuje své vlastní transakce. Všechny dávky zkopírované až do bodu chyby jsou potvrzeny; dávka obsahující duplicitní klíč se vrátí zpět a operace hromadného kopírování se zastaví před zpracováním jiných dávek.

Důležité

Tato ukázka se nespustí, pokud jste nevytvořili pracovní tabulky, jak je popsáno v příkladu hromadného kopírování. Tento kód je k dispozici k předvedení syntaxe pouze pro použití sqlBulkCopy . Pokud jsou zdrojové a cílové tabulky umístěny ve stejné instanci SQL Serveru, je jednodušší a rychlejší použít příkaz Jazyka Transact-SQLINSERT … SELECT ke kopírování dat.

var connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
           new(connectionString))
{
    sourceConnection.Open();

    //  Delete all from the destination table.
    SqlCommand commandDelete = new()
    {
        Connection = sourceConnection,
        CommandText =
        "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
    };
    commandDelete.ExecuteNonQuery();

    //  Add a single row that will result in duplicate key
    //  when all rows from source are bulk copied.
    //  Note that this technique will only be successful in
    //  illustrating the point if a row with ProductID = 446
    //  exists in the AdventureWorks Production.Products table.
    //  If you have made changes to the data in this table, change
    //  the SQL statement in the code to add a ProductID that
    //  does exist in your version of the Production.Products
    //  table. Choose any ProductID in the middle of the table
    //  (not first or last row) to best illustrate the result.
    SqlCommand commandInsert = new()
    {
        Connection = sourceConnection,
        CommandText =
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" +
        "INSERT INTO " + "dbo.BulkCopyDemoMatchingColumns " +
        "([ProductID], [Name] ,[ProductNumber]) " +
        "VALUES(446, 'Lock Nut 23','LN-3416');" +
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
    };
    commandInsert.ExecuteNonQuery();

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

    // Set up the bulk copy object.
    // Note that when specifying the UseInternalTransaction
    // option, you cannot also specify an external transaction.
    // Therefore, you must use the SqlBulkCopy construct that
    // requires a string for the connection, rather than an
    // existing SqlConnection object.
    using (SqlBulkCopy bulkCopy = new(
               connectionString, SqlBulkCopyOptions.KeepIdentity |
               SqlBulkCopyOptions.UseInternalTransaction))
    {
        bulkCopy.BatchSize = 10;
        bulkCopy.DestinationTableName =
            "dbo.BulkCopyDemoMatchingColumns";

        // Write from the source to the destination.
        // This should fail with a duplicate key error
        // after some of the batches have been copied.
        try
        {
            bulkCopy.WriteToServer(reader);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            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 sourceConnection to the AdventureWorks database.
        Using sourceConnection As SqlConnection = _
           New SqlConnection(connectionString)
            sourceConnection.Open()

            ' Delete all from the destination table.
            Dim commandDelete As New SqlCommand
            commandDelete.Connection = sourceConnection
            commandDelete.CommandText = _
               "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
            commandDelete.ExecuteNonQuery()

            ' Add a single row that will result in duplicate key
            ' when all rows from source are bulk copied.
            ' Note that this technique will only be successful in
            ' illustrating the point if a row with ProductID = 446
            ' exists in the AdventureWorks Production.Products table.
            ' If you have made changes to the data in this table, change
            ' the SQL statement in the code to add a ProductID that
            ' does exist in your version of the Production.Products
            ' table. Choose any ProductID in the middle of the table
            ' (not first or last row) to best illustrate the result.
            Dim commandInsert As New SqlCommand
            commandInsert.Connection = sourceConnection
            commandInsert.CommandText = _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" & _
               "INSERT INTO dbo.BulkCopyDemoMatchingColumns " & _
               "([ProductID], [Name] ,[ProductNumber]) " & _
               "VALUES(446, 'Lock Nut 23','LN-3416');" & _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
            commandInsert.ExecuteNonQuery()

            ' 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()

            ' Set up the bulk copy object.
            ' Note that when specifying the UseInternalTransaction option,
            ' you cannot also specify an external transaction. Therefore,
            ' you must use the SqlBulkCopy construct that requires a string
            ' for the connection, rather than an existing SqlConnection object.
            Using bulkCopy As SqlBulkCopy = New SqlBulkCopy(connectionString, _
             SqlBulkCopyOptions.UseInternalTransaction Or _
             SqlBulkCopyOptions.KeepIdentity)
                bulkCopy.BatchSize = 10
                bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns"

                ' Write from the source to the destination.
                ' This should fail with a duplicate key error
                ' after some of the batches have already been copied.
                Try
                    bulkCopy.WriteToServer(reader)

                Catch ex As Exception
                    Console.WriteLine(ex.Message)

                Finally
                    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 Sub

    Private Function GetConnectionString() As String
        Throw New NotImplementedException()
    End Function
End Module

Použití existujících transakcí

V konstruktoru SqlBulkCopy můžete zadat existující SqlTransaction objekt jako parametr. V takové situaci se operace hromadného kopírování provádí v existující transakci a v transakčním stavu se neprovádí žádná změna (to znamená, že není potvrzena ani přerušena). To umožňuje aplikaci zahrnout operaci hromadného kopírování do transakce s jinými databázovými operacemi. Pokud však nezadáte SqlTransaction objekt a předáte odkaz null a připojení má aktivní transakci, vyvolá se výjimka.

Pokud potřebujete vrátit zpět celou operaci hromadného kopírování, protože dojde k chybě, nebo pokud by se hromadná kopie měla provést jako součást většího procesu, který lze vrátit zpět, můžete SqlTransaction poskytnout objekt konstruktoru SqlBulkCopy .

Následující konzolová aplikace je podobná prvnímu příkladu (bez transakce), s jednou výjimkou: v tomto příkladu je operace hromadného kopírování zahrnuta do větší externí transakce. Když dojde k chybě porušení primárního klíče, celá transakce se vrátí zpět a do cílové tabulky se nepřidají žádné řádky.

Důležité

Tato ukázka se nespustí, pokud jste nevytvořili pracovní tabulky, jak je popsáno v příkladu hromadného kopírování. Tento kód je k dispozici k předvedení syntaxe pouze pro použití sqlBulkCopy . Pokud jsou zdrojové a cílové tabulky umístěny ve stejné instanci SQL Serveru, je jednodušší a rychlejší použít příkaz Jazyka Transact-SQLINSERT … SELECT ke kopírování dat.

var connectionString = GetConnectionString();
// Open a sourceConnection to the AdventureWorks database.
using (SqlConnection sourceConnection =
           new(connectionString))
{
    sourceConnection.Open();

    //  Delete all from the destination table.
    SqlCommand commandDelete = new()
    {
        Connection = sourceConnection,
        CommandText =
        "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
    };
    commandDelete.ExecuteNonQuery();

    //  Add a single row that will result in duplicate key
    //  when all rows from source are bulk copied.
    //  Note that this technique will only be successful in
    //  illustrating the point if a row with ProductID = 446
    //  exists in the AdventureWorks Production.Products table.
    //  If you have made changes to the data in this table, change
    //  the SQL statement in the code to add a ProductID that
    //  does exist in your version of the Production.Products
    //  table. Choose any ProductID in the middle of the table
    //  (not first or last row) to best illustrate the result.
    SqlCommand commandInsert = new()
    {
        Connection = sourceConnection,
        CommandText =
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" +
        "INSERT INTO " + "dbo.BulkCopyDemoMatchingColumns " +
        "([ProductID], [Name] ,[ProductNumber]) " +
        "VALUES(446, 'Lock Nut 23','LN-3416');" +
        "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
    };
    commandInsert.ExecuteNonQuery();

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

    //Set up the bulk copy object inside the transaction.
    using (SqlConnection destinationConnection =
               new(connectionString))
    {
        destinationConnection.Open();

        using (SqlTransaction transaction =
                   destinationConnection.BeginTransaction())
        {
            using (SqlBulkCopy bulkCopy = new(
                       destinationConnection, SqlBulkCopyOptions.KeepIdentity,
                       transaction))
            {
                bulkCopy.BatchSize = 10;
                bulkCopy.DestinationTableName =
                    "dbo.BulkCopyDemoMatchingColumns";

                // Write from the source to the destination.
                // This should fail with a duplicate key error.
                try
                {
                    bulkCopy.WriteToServer(reader);
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    transaction.Rollback();
                }
                finally
                {
                    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 sourceConnection to the AdventureWorks database.
        Using sourceConnection As SqlConnection = _
           New SqlConnection(connectionString)
            sourceConnection.Open()

            ' Delete all from the destination table.
            Dim commandDelete As New SqlCommand
            commandDelete.Connection = sourceConnection
            commandDelete.CommandText = _
               "DELETE FROM dbo.BulkCopyDemoMatchingColumns"
            commandDelete.ExecuteNonQuery()

            ' Add a single row that will result in duplicate key
            ' when all rows from source are bulk copied.
            ' Note that this technique will only be successful in
            ' illustrating the point if a row with ProductID = 446
            ' exists in the AdventureWorks Production.Products table.
            ' If you have made changes to the data in this table, change
            ' the SQL statement in the code to add a ProductID that
            ' does exist in your version of the Production.Products
            ' table. Choose any ProductID in the middle of the table
            ' (not first or last row) to best illustrate the result.
            Dim commandInsert As New SqlCommand
            commandInsert.Connection = sourceConnection
            commandInsert.CommandText = _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns ON;" & _
               "INSERT INTO dbo.BulkCopyDemoMatchingColumns " & _
               "([ProductID], [Name] ,[ProductNumber]) " & _
               "VALUES(446, 'Lock Nut 23','LN-3416');" & _
               "SET IDENTITY_INSERT dbo.BulkCopyDemoMatchingColumns OFF"
            commandInsert.ExecuteNonQuery()

            ' 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()

            ' Set up the bulk copy object inside the transaction.
            Using destinationConnection As SqlConnection = _
               New SqlConnection(connectionString)
                destinationConnection.Open()

                Using transaction As SqlTransaction = _
                  destinationConnection.BeginTransaction()

                    Using bulkCopy As SqlBulkCopy = New _
                      SqlBulkCopy(destinationConnection, _
                         SqlBulkCopyOptions.KeepIdentity, transaction)
                        bulkCopy.BatchSize = 10
                        bulkCopy.DestinationTableName = _
                         "dbo.BulkCopyDemoMatchingColumns"

                        ' Write from the source to the destination.
                        ' This should fail with a duplicate key error.
                        Try
                            bulkCopy.WriteToServer(reader)
                            transaction.Commit()

                        Catch ex As Exception
                            Console.WriteLine(ex.Message)
                            transaction.Rollback()

                        Finally
                            reader.Close()
                        End Try
                    End Using
                End Using
            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 Sub

    Private Function GetConnectionString() As String
        Throw New NotImplementedException()
    End Function
End Module

Viz také