2014-06-17 1 views
0

SqlBulkCopy를 사용하여 서버에 레코드 일괄 처리를 삽입하고 있습니다. 고유 한 제약으로 인해 하나의 레코드가 실패하면 전체 일괄 처리를 롤백하지 않고 대신 기존 레코드를 업데이트하려고합니다.한 삽입이 실패 할 때 SqlBulkCopy 트랜잭션 롤백을 중지하십시오.

벌크 삽입이 완료되면 실패한 레코드 키 값을 기록한 다음 되돌아 가서 개별적으로 주소를 지정하기를 바랬습니다.

그러나 SqlBulkCopy가 실패시 트랜잭션을 롤백하지 않거나 실패한 레코드에 대한 정보를 얻는 방법을 알 수 없습니다.

레코드를 SqlBulkCopy DataTable에 추가하기 전에 존재하는지 확인할 수는 있지만 상당한 오버 헤드가 추가됩니다.

벌크 삽입 후에 스테이징 테이블과 다른 sproc을 사용하여 응답을 표시하는 답변 here을 확인했지만 sproc은 각 레코드를 개별적으로 처리하여 새로 삽입하거나 업데이트해야한다고 생각합니다. 기존 레코드 - 매우 많은 시간이 소요됩니다.

다른 도움말이나 지난 4 년 동안 변경된 사항이 없습니까?

답변

1

병합 성명을 사용하지 않는 것이 좋습니다. 많은 사람들이 처음으로 Use Caution with SQL Server's MERGE Statement을 보았고, 개인적으로 IMHO를 따르기가 어렵고 간단한 insert update 문 (너무 감미로운 구문 설탕이 아닌)을 제공합니다.

INSERT INTO A 
SELECT * 
FROM #B B 
     LEFT OUTER JOIN A 
       ON A.ID = B.ID 
WHERE A.ID IS NULL 

또는

UPDATE A 
SET BLAH = 'BLAH'  
FROM A 
     INNER JOIN #B B 
       ON B.ID = A.ID 

당신은 당신은 당신이 찾고있는 것을 처리 할 수있는 SSIS를 조사 할 수 있습니다 순수한 SQL보다는 도구에 설정되어있는 경우.

+0

나는 위와 같은 간단한 진술을 통해 당신이 옳다고 생각합니다. 왜 병합을 사용해야합니까? – Graeme

2

SqlBulkCopy를 사용하지 마십시오.

직접.

임시 테이블에 삽입 (또한 SqlBulkCopy의 끔찍한 잠금 동작 방지) 한 다음 적절한 규칙을 사용하여 최종 테이블에 병합하십시오.

간단합니다. 이렇게하면 모든 일괄 업데이트가 수행됩니다.

+0

머지 (MERGE)에 대해 몰랐기 때문에 숙제를해야 할 것입니다. 끔찍한 잠금 동작을 확장 할 수 있습니까? – Graeme

+0

SqlBulkCopy는 테이블 배타적 잠금을 얻으려고합니다. 문제는 아니지만 대기 기간없이 시도합니다. 동시에 여러 개를 실행하면 항상 실패합니다. 30 초 동안 반복적으로 시도한 후 포기합니다. 문제는 결코 기다리지 않기 때문에 잠금이있는 바쁜 테이블에서 항상 실패합니다. 30 초를 기다리면 실제로 더 잘 작동합니다. 우리는 질량 대량 삽입 - 많은 msame 시간 (calcualtion을하고 많은 컴퓨터) 및 완전히 모든 현명한 성능을 죽인. – TomTom

+0

일괄 업로드를 제외하고는 읽기 전용 테이블이므로 절 문제는 아닙니다. – Graeme

관련 문제