首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在bulkCopy.WriteToServer后返回结果

如何在bulkCopy.WriteToServer后返回结果
EN

Stack Overflow用户
提问于 2013-10-01 11:12:16
回答 3查看 10.2K关注 0票数 4

基于接受的答案更新

代码语言:javascript
复制
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;

我将BulkCopy类用于大型insert,它工作得很好。

执行WriteToServer并将数据保存到数据库后

我不想知道是否所有的数据都保存成功了,所以我可以返回true/false,因为我需要保存所有或什么都不保存?

代码语言:javascript
复制
    var bulkCopy = new SqlBulkCopy(connection);

    bulkCopy.DestinationTableName = "table";

    bulkCopy.ColumnMappings...

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

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-10-01 11:37:49

如果没有异常地完成对WriteToServer的调用,则所有行都已保存并位于磁盘上。这只是Server的标准语义。批量复制没有什么特别之处。

和所有其他的DML一样,SqlBulkCopy也是什么都不是。除非您配置了未配置的批处理大小。

代码语言:javascript
复制
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
    }
}

我已经添加了与最佳实践相一致的示例代码。

票数 5
EN

Stack Overflow用户

发布于 2013-10-01 11:21:16

除了查找/捕获WriteToServer()方法引发的任何异常之外,没有任何直接的方法来识别流程是否成功完成。

另一种方法可能是检查数据库中的记录数,然后在进程完成后检查记录的数量--不同的是插入的数量。将此值与要插入的记录数进行比较,可以给出失败或成功的概念。然而,这并不是愚蠢的证明,特别是如果有其他进程插入/删除记录。

然而,这些技术结合TransactionScope - http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx -或类似的技术应该可以实现您所需要的。

编辑

默认情况下,每个insert操作都作为批处理处理;如果操作在特定批处理中失败,则该批处理将回滚,而不是在其之前插入。

但是,如果将内部事务应用于大容量操作而不是中的失败,则任何行都可以回滚整个结果集。例如;

代码语言:javascript
复制
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();
   }
}

上述操作中的任何一个错误都会导致整个操作回滚。请在http://msdn.microsoft.com/en-us/library/tchktcdk.aspx上查看有关此问题的更多详细信息。

票数 1
EN

Stack Overflow用户

发布于 2013-10-01 11:15:56

从这个函数的文档中,下面的片段建议您捕获抛出的任何异常,否则您可以认为操作是成功的。

代码语言:javascript
复制
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString))
{
     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();
     }
}

如果您想要确定,在大容量复制完成后,对数据库执行一个查询以检查行是否在那里。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19114696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档