How to return result after bulkCopy.WriteToServer

c# sqlbulkcopy sql-server sql-server-2008

Question

UPDATE based on accepted answer:

bool success = false;
using (var bulkCopy = new SqlBulkCopy(connection)) //using!
{
    connection.Open();

    //explicit isolation level is best-practice
    using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        bulkCopy.DestinationTableName = "table";
        bulkCopy.ColumnMappings...

        using (var dataReader = new ObjectDataReader<SomeObject>(paths))
        {            
            bulkCopy.WriteToServer(dataReader);
            success = true;
        }

        tran.Commit(); //commit, will not be called if exception escapes
    }
}
return success;

I use BulkCopy class for large insert and it works fine.
After execute WriteToServer and saving data to database
I wan't to know are all data saved successfully so I can return true/false because I need to save all or nothing?

    var bulkCopy = new SqlBulkCopy(connection);

    bulkCopy.DestinationTableName = "table";

    bulkCopy.ColumnMappings...

    using (var dataReader = new ObjectDataReader<SomeObject>(paths))
    {
        try
        {
        bulkCopy.WriteToServer(dataReader);
        }
        catch(Exception ex){ ... }    
}

Accepted Answer

If the call to WriteToServer completed without exceptions, all rows were saved and are on disk. This is just the standard semantics for SQL Server DML. Nothing special with bulk copy.

Like all other DML, SqlBulkCopy is all-or-nothing as well. Except if you configure a batch size which you did not.

using (var bulkCopy = new SqlBulkCopy(connection)) //using!
{
    connection.Open();

    //explicit isolation level is best-practice
    using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        bulkCopy.DestinationTableName = "table";
        bulkCopy.ColumnMappings...

        using (var dataReader = new ObjectDataReader<SomeObject>(paths))
        {
            //try
            //{
            bulkCopy.WriteToServer(dataReader, /*here you set some options*/);
            //}
            //catch(Exception ex){ ... } //you need no explicit try-catch here
        }

        tran.Commit(); //commit, will not be called if exception escapes
    }
}

I've added you sample code that I aligned with best-practices.


Popular Answer

There is no direct way of identifying if the process was completed successfully or not, other than to look for/catch any exceptions raised by WriteToServer() method.

An alternative approach might be to check the number of records in the database, and then check the number of records after the process completes - The difference being the number that were inserted. Comparing this value against the numbers of records to be inserted could give an idea of failure or success. However, this is not fool proof particularly if there are other process inserting/deleting records.

However, these techniques in conjunction with TransactionScope - http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx - or something similar should achieve what you require.

EDIT

By Default each insert operation is processed as a batch; if the operation fails in a particular batch then that batch is rolled back, not any inserted before it.

However, If an internal transaction is applied to the bulk operation than a failure in any row can roll back the entire result set. For Example;

using (SqlBulkCopy bulkCopy =
   new SqlBulkCopy(connectionString, SqlBulkCopyOptions.KeepIdentity
                   | SqlBulkCopyOptions.UseInternalTransaction))
{
   bulkCopy.BatchSize = 10;
   bulkCopy.DestinationTableName = "dbo.BulkCopyDemoMatchingColumns";

   try
   {
      bulkCopy.WriteToServer(reader);
   }
   catch (Exception ex)
   {
      Console.WriteLine(ex.Message);
   }
   finally
   {
      bulkCopy.Close();
   }
}

An error in any of the above operation would cause the entire operation to roll back. See more details on this at http://msdn.microsoft.com/en-us/library/tchktcdk.aspx.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why