SqlBulkCopy.WriteToServer (DataTable) 행 단위로 : 매우 느림

c# sqlbulkcopy

문제

csv 파일을 데이터베이스 테이블로 가져 오는 응용 프로그램을 만들어야했습니다. csv 파일은 ~500rows ~30columns~30columns 으며 신뢰할 수없는 소스 (손상된 데이터가 포함되었을 수 있음)의 파일입니다.

나는 이것을 CSV->DataTable->SqlBulkCopy.WriteToServer(DataTable) 처럼했다. 그리고 그것은 비 - 로컬 SQL 서버에 약 4 초 동안 500 개의 레코드를 처리하는데, 큰 문제는 아닙니다. 하지만 csv가 손상된 데이터 (잘못된 날짜 형식, 정수 오버플로 등)를 포함 할 수 있기 때문에 오류 증명을 생성하고 좋은 행을 가져 와서 잘못된 행을 건너 뛸 수 밖에 없었습니다. 손상된 데이터를 DataTable로 처리 할 때 DataTable을 DataBase로 가져올 때 문제가 발생하지 않습니다. 내가 한 것은 DB에서 행별로 행을 추가하는 TRY {}입니다.

int Row = 0;
//csvFileData is the DataTable filled with csv data

foreach(DataRow RowToAdd in csvFileData.Rows) 
{
    //here it spents 1-2% of the time (problem not in DT  row by row processing)
    Row++;
    DataTable TempDT = new DataTable();
    TempDT = csvFileData.Clone();
    TempDT.ImportRow(RowToAdd);

    try 
    { 
        //here it spents 98% of the time
        s.WriteToServer(TempDT);

    } 
    catch(Exception importex)
    {
        Console.WriteLine("Couldn't import {0} row, reason", Row, importex.Message);
    }

}

호출 : s.WriteToServer(scvFileData);
제 경우에는 한 번 좋지 않습니다.

끝내면 정말 잘 돌아갑니다. 문제는 실행 시간이 15 초로 길다는 점입니다. 그것은 각 행에 대해 DB와의 앞뒤 통신을하기 때문입니다. 이 문제를 어떻게 해결할 수 있습니까? 나는 DataBase 테이블 디자인의 로컬 복제품과 같은 것을 에뮬레이션하는 것에 대해 생각하고있었습니다. {}을 (를) 모든 행마다 시도한 다음 잘못된 데이터를 제외하고 그 후에 전체 DataTable (불량 행이 제거됨)을 가져 오는 데이터를 가져옵니다. 또는 행별로 비동기 가져 오기를 수행하는 경우에도 행이 순서대로 정렬되거나 누락되거나 복제 될 수 있다고 생각합니다. 팁을 줄 수 있습니까?

인기 답변

앞서 언급 한 것처럼 분명한 해결책은 데이터가 CSV 파일에서 읽혀질 때 데이터를 확인하고 데이터 테이블을 '양호 행'으로 채우는 것입니다.

검증에 데이터 유형 검사가 포함 된 경우 (예 : 대상 시스템 (여기서는 SQL 서버)에서 문자열을 변환 할 수있는 경우), 즉 SQL Server에 이미 구현 된 재 프로그래밍 파싱 / 변환 논리와 같은 논리를 여기서 복제합니다. 이것은 큰 문제는 아니지만 설계 측면에서 보면 반드시 똑똑하지는 않습니다.

실제로 BULK INSERT 명령을 사용하여 CSV 파일을 SQL Server로 직접 가져올 수 있습니다.

따라서 다른 방법은 서버의 임시 테이블로 원시 데이터를 가져온 다음 데이터 유형 검사를 수행하는 것입니다. SQL 2005 이상을 실행하면 매우 쉽습니다. ISDATEISNUMERIC 과 같은 기능을 소개합니다.

BULK INSERT CSVRawData FROM 'c:\csvtest.txt' WITH (
  FIELDTERMINATOR = ',', ROWTERMINATOR = '\n'
)

INSERT INTO FinalTable 
SELECT * from CSVRawData
 WHERE ISDATE(DateField) 
   and ISNUMERIC (NumericField)

다음과 같은 경우 개인적으로이 방법을 사용합니다.

  • CSV 파일의 형식이 고정되어 있습니다.
  • 무결성 검사가 SQL로 작성하기 쉽습니다.

예를 들어 우리는 그런 식으로 로그 파일을 분석합니다. 50 개의 Mio + 행을 포함하고 있으며 일부는 손상되었거나 단순히 관심이 없습니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.