SQLBulkCopy的任何方式“插入或更新,如果存在”?
我需要定期更新一个非常大的表,SQLBulkCopy是完美的,只有我有一个2列索引,可以防止重复。 有没有办法使用SQLBulkCopy作为“插入或更新,如果存在”?
如果没有,最有效的方法是什么? 我再次谈论一张包含数百万条记录的表格。
谢谢
我会将数据批量加载到临时临时表中,然后在最终表中进行upsert。 有关执行upsert的示例,请参阅http://www.databasejournal.com/features/mssql/article.php/3739131/UPSERT-Functionality-in-SQL-Server-2008.htm 。
不是一步到位,而是在SQL Server 2008中 ,您可以:
- 批量加载到临时表中
- 应用
MERGE
语句来更新/插入真实表
阅读有关MERGE语句的更多信息
我发布了一个nuget包(SqlBulkTools)来解决这个问题。
这是一个可以实现批量upsert的代码示例。
var bulk = new BulkOperations(); var books = GetBooks(); using (TransactionScope trans = new TransactionScope()) { using (SqlConnection conn = new SqlConnection(ConfigurationManager .ConnectionStrings["SqlBulkToolsTest"].ConnectionString)) { bulk.Setup() .ForCollection(books) .WithTable("Books") .AddAllColumns() .BulkInsertOrUpdate() .MatchTargetOn(x => x.ISBN) .Commit(conn); } trans.Complete(); }
对于非常大的表,可以选择添加表锁并临时禁用非聚簇索引。 有关更多示例,请参见SqlBulkTools文档 。
而不是创建一个新的临时表,BTW消耗更多的空间和内存。
我用INSTEAD OF INSERT创建了一个Trigger,并在MERGE语句中使用。
但是不要忘记在SqlBulkCopy中添加参数SqlBulkCopyOptions.FireTriggers。
这是我的两分钱。
另一种方法是不使用临时表,而是使用带有表值参数的存储过程。 将数据表传递给sp并在那里进行合并。