如何在 bulkCopy.WriteToServer 之后返回结果
本文关键字:之后 返回 结果 WriteToServer bulkCopy | 更新日期: 2023-09-27 18:33:23
>基于接受的答案更新:
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
类用于大型插入,它工作正常。
执行WriteToServer
并将数据保存到数据库
后,我不知道所有数据是否都已成功保存,因此我可以返回true/false
因为我需要保存全部或什么都不保存?
var bulkCopy = new SqlBulkCopy(connection);
bulkCopy.DestinationTableName = "table";
bulkCopy.ColumnMappings...
using (var dataReader = new ObjectDataReader<SomeObject>(paths))
{
try
{
bulkCopy.WriteToServer(dataReader);
}
catch(Exception ex){ ... }
}
如果对WriteToServer
调用完成且无异常,则所有行都已保存并位于磁盘上。这只是SQL Server DML的标准语义。批量复制没有什么特别之处。
像所有其他DML一样,SqlBulkCopy
也是全有或全无的。除非您配置了未配置的批大小。
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
}
}
我添加了与最佳实践一致的示例代码。
查找/捕获WriteToServer()
方法引发的任何异常外,没有直接的方法可以确定该过程是否已成功完成。
另一种方法可能是检查数据库中的记录数,然后在该过程完成后检查记录数 - 区别在于插入的数量。 将此值与要插入的记录数进行比较可能会得出失败或成功的想法。 但是,这不是万无一失的,尤其是在有其他进程插入/删除记录的情况下。
但是,这些技术与TransactionScope
(http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx(或类似技术相结合,应该可以满足您的需求。
编辑
默认情况下,每个插入操作都作为批处理进行处理;如果操作在特定批处理中失败,则会回滚该批处理,而不是在其之前插入的任何操作。
但是,如果将内部事务应用于批量操作,则任何行中的故障都可以回滚整个结果集。 例如;
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。
从此函数的文档中,以下代码片段建议您应该捕获引发的任何异常,否则您可以认为操作成功。
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();
}
}
如果要超级确定,请在大容量复制完成后对数据库执行查询以检查行是否存在。