복붙노트

[SQL] "경우가 존재 삽입 또는 업데이트"SqlBulkCopy의 할 수있는 방법?

SQL

"경우가 존재 삽입 또는 업데이트"SqlBulkCopy의 할 수있는 방법?

나는 정기적으로 매우 큰 테이블을 업데이트 할 필요 SqlBulkCopy의 내가 방지 중복이 2 열 인덱스가 유일한 것으로, 그 최적입니다. "삽입 또는 업데이트가있는 경우"로 SqlBulkCopy의를 사용하는 방법이 있나요?

그렇지 않다면, 그렇게하는 가장 효율적인 방법은 무엇입니까? 다시 말하지만, 나는 수백만 개의 레코드가있는 테이블에 대해 이야기하고있다.

감사합니다

해결법

  1. ==============================

    1.나는 임시 준비 테이블에 대량로드 데이터는 다음 최종 테이블에 대한 upsert을 할 것입니다. upsert을하는 예는 http://www.databasejournal.com/features/mssql/article.php/3739131/UPSERT-Functionality-in-SQL-Server-2008.htm를 참조하십시오.

    나는 임시 준비 테이블에 대량로드 데이터는 다음 최종 테이블에 대한 upsert을 할 것입니다. upsert을하는 예는 http://www.databasejournal.com/features/mssql/article.php/3739131/UPSERT-Functionality-in-SQL-Server-2008.htm를 참조하십시오.

  2. ==============================

    2.나는이 문제를 해결하기 위해 nuget 패키지 (SqlBulkTools)를 발표했다.

    나는이 문제를 해결하기 위해 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<Book>()
                .ForCollection(books)
                .WithTable("Books")
                .AddAllColumns()
                .BulkInsertOrUpdate()
                .MatchTargetOn(x => x.ISBN)
                .Commit(conn);
        }
    
        trans.Complete();
    }
    

    매우 큰 테이블의 경우, 테이블 잠금 일시적으로 비활성화 클러스터되지 않은 인덱스를 추가 할 수있는 옵션이 있습니다. 추가 예제 SqlBulkTools 문서를 참조하십시오.

  3. ==============================

    3.하지 한 단계에 있지만, SQL Server 2008의, 당신은 할 수 :

    하지 한 단계에 있지만, SQL Server 2008의, 당신은 할 수 :

    MERGE 문에 대해 자세히보기

  4. ==============================

    4.대신 BTW 더 많은 공간과 메모리를 소비하는 새로운 임시 테이블을 만들 수 있습니다.

    대신 BTW 더 많은 공간과 메모리를 소비하는 새로운 임시 테이블을 만들 수 있습니다.

    내가 대신 INSERT와 MERGE 문 내부 사용과 트리거를 만들었습니다.

    그러나 SqlBulkCopy의에서 매개 변수 SqlBulkCopyOptions.FireTriggers를 추가 잊지 마세요.

    이것은 내 두 센트입니다.

  5. ==============================

    5.또 다른 대안은 임시 테이블을 사용하지만 테이블 반환 매개 변수와 저장 프로 시저를 사용하지 않는 것입니다. SP로 데이터 테이블에 합격이 병합을한다.

    또 다른 대안은 임시 테이블을 사용하지만 테이블 반환 매개 변수와 저장 프로 시저를 사용하지 않는 것입니다. SP로 데이터 테이블에 합격이 병합을한다.

  6. ==============================

    6.@Ivan에서 힌트를 얻었다. 해야 할 수 있습니다 사람들을 위해, 여기에 내가 무슨 짓을했는지.

    @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
    
  7. from https://stackoverflow.com/questions/4889123/any-way-to-sqlbulkcopy-insert-or-update-if-exists by cc-by-sa and MIT license