C# “任何方式复制”;插入或更新(如果存在)";?

C# “任何方式复制”;插入或更新(如果存在)";?,c#,sql,sql-server,performance,sqlbulkcopy,C#,Sql,Sql Server,Performance,Sqlbulkcopy,我需要定期更新一个非常大的表,SQLBulkCopy非常适合这样做,只是我有一个防止重复的2列索引。是否有一种方法可以将SQLBulkCopy用作“插入或更新(如果存在)” 如果没有,最有效的方法是什么?再一次,我说的是一个有数百万条记录的表格 谢谢我会将数据批量加载到一个临时暂存表中,然后向上插入到最终的表中。请参阅,以获取执行upsert的示例。不是一步完成的,而是在SQL Server2008中,您可以: 批量加载到暂存表中 应用MERGE语句更新/插入实际表 阅读有关的更多信息另一种

我需要定期更新一个非常大的表,SQLBulkCopy非常适合这样做,只是我有一个防止重复的2列索引。是否有一种方法可以将SQLBulkCopy用作“插入或更新(如果存在)”

如果没有,最有效的方法是什么?再一次,我说的是一个有数百万条记录的表格


谢谢

我会将数据批量加载到一个临时暂存表中,然后向上插入到最终的表中。请参阅,以获取执行upsert的示例。

不是一步完成的,而是在SQL Server2008中,您可以:

  • 批量加载到暂存表中
  • 应用
    MERGE
    语句更新/插入实际表

阅读有关

的更多信息另一种选择是不使用临时表,而是使用带有表值参数的存储过程。将一个数据表传递给sp并在那里进行合并。

而不是创建一个新的临时表,这会消耗更多的空间和内存

我用INSERT而不是INSERT创建了一个触发器,并在MERGE语句中使用

但不要忘记在SqlBulkCopy中添加参数SqlBulkCopyOptions.FireTriggers


这是我的两分钱。

我发布了一个nuget包(SqlBulkTools)来解决这个问题

下面是一个实现批量升级的代码示例

var bulk = new BulkOperations();
var books = GetBooks();

using (TransactionScope trans = new TransactionScope())
{
    using (SqlConnection conn = new SqlConnection(ConfigurationManager
    .ConnectionStrings["SqlBulkToolsTest"].ConnectionString))
    {
        bulk.Setup<Book>()
            .ForCollection(books)
            .WithTable("Books")
            .AddAllColumns()
            .BulkInsertOrUpdate()
            .MatchTargetOn(x => x.ISBN)
            .Commit(conn);
    }

    trans.Complete();
}
var bulk=新的BulkOperations();
var books=GetBooks();
使用(TransactionScope trans=new TransactionScope())
{
使用(SqlConnection conn=newsqlconnection(ConfigurationManager
.ConnectionString[“SqlBulkToolsTest”].ConnectionString)
{
bulk.Setup()
.收藏(书籍)
.WithTable(“书籍”)
.AddAllColumns()
.BulkInsertOrUpdate()
.MatchTargetOn(x=>x.ISBN)
.提交(康涅狄格州);
}
trans.Complete();
}

对于非常大的表,可以选择添加表锁和临时禁用非聚集索引。有关更多示例,请参阅。

从@Ivan那里得到了提示。对于那些可能需要帮助的人,以下是我所做的

create trigger yourschma.Tr_your_triger_name
    on yourschma.yourtable
    instead of INSERT
    as
    merge into yourschma.yourtable as target
    using inserted as source
    on (target.yourtableID = source.yourtableID)
    when matched then
        update
        set target.ID     = source.ID,
            target.some_column = source.some_column,
            target.Amount                       = source.Amount
    when not matched by target then
        insert (some_column, Amount)
        values (source.some_column, source.Amount);
go

我对SSIS不太熟悉,它将如何帮助完成这项任务?这是一项非常昂贵的业务。创建一个临时表,然后合并。我不得不说,这个库充满了优点。我必须编写一个windows服务来完成一些ETL工作,数据库交互不足以证明哪怕是一个MicroORM,而这个库SqlBulkTools是完美的。非常感谢。干得好!文档链接死了(404)。SqlBulkTools被卖给了ZZZ项目。现在是2020年,我正在使用这个包。性能非常好,这正是我批量插入或更新所需要的!同样工作很好,有没有关于使用CancellationToken来拯救部分操作的想法(因为这些操作可能会运行很长时间)?