2008-11-11 4 views
1

기본적으로 Excel 파일에 많은 데이터를 삽입해야합니다. OleDB 연결을 만드는 것이 가장 빠른 방법 인 것처럼 보이지만 메모리 문제가있는 것으로 나타났습니다. INSERT 쿼리를 실행하면 프로세스에서 사용하는 메모리가 계속 증가하는 것처럼 보입니다. Excel 파일로 출력 할 때만 메모리를 축소했습니다 (메모리가 Excel에 출력되지 않고 안정적으로 유지됩니다). 나는 닫고 각 워크 시트 사이의 연결을 다시 열지 만 이것은 Dispose()와 마찬가지로 메모리 사용에 영향을 미치지 않습니다. 상대적으로 작은 데이터 세트로 확인할 수 있기 때문에 데이터가 성공적으로 기록됩니다. 누군가 통찰력을 가지고 있다면, 그것은 인정 될 것입니다.ADO.NET + 방대한 INSERT + Excel + C# = "나쁜 시간"입니까?

initializeADOConn는()이 생성자

initADOConnInsertComm (에서 호출)는 삽입 매개 변수 삽입 쿼리를

writeRecord을() 새로운 레코드가 기록 될 때마다가 호출 만듭니다. 필요에 따라 새 워크 시트가 만들어집니다.

public bool initializeADOConn() 
     { 
      /* Set up the connection string and connect.*/ 
      string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" + 
       "Data Source=" + this.destination + ";Extended Properties=\"Excel 8.0;HDR=YES;\""; 
      //DbProviderFactory factory = 
       //DbProviderFactories.GetFactory("System.Data.OleDb"); 
      conn = new OleDbConnection(connectionString); 
      conn.ConnectionString = connectionString; 
      conn.Open(); 

      /* Intialize the insert command. */ 
      initADOConnInsertComm(); 
      return true; 
     } 
    public override bool writeRecord(FileListerFileInfo file) 
      { 
       /* If all available sheets are full, make a new one. */ 
       if (numWritten % EXCEL_MAX_ROWS == 0) 
       { 
        conn.Close(); 
        conn.Open(); 
        createNextSheet(); 
       } 
       /* Count this record as written. */ 
       numWritten++; 
       /* Get all of the properties of the FileListerFileInfo record and add 
       * them to the parameters of the insert query. */ 
       PropertyInfo[] properties = typeof(FileListerFileInfo).GetProperties(); 
       for (int i = 0; i < insertComm.Parameters.Count; i++) 
        insertComm.Parameters[i].Value = properties[i].GetValue(file, null); 
       /* Add the record. */ 
       insertComm.ExecuteNonQuery(); 

       return true; 
      } 

편집 :

아니, 난 전혀 Excel을 사용하지 마십시오. Interop.Excel의 성능 저하로 인해 의도적으로 Interop.Excel을 피할 수 있습니다.

답변

2

대답은 예, 당신은 나쁜 시간을 동일 않는 설명하는 식.

데이터베이스를 편리하게 사용할 수 있으면 (SQL Server 또는 Access가 적합) 데이터베이스 테이블에 모든 삽입 작업을 수행 한 다음 테이블을 한 번에 Excel 스프레드 시트로 내보낼 수 있습니다.

일반적으로 데이터베이스는 많은 수의 삽입물을 처리하는 데 적합하지만 스프레드 시트는 그렇지 않습니다.

+0

이 응답을 읽은 후 (그리고 내 상사를 연결하는 데 약 12 ​​가지 이유가있는 이유는 무엇입니까?), 나는 경영진이 그 질문에 의존하지 않을 것이라고 확신했습니다. 이미 출력 옵션 배열이 있으므로 중요하지 않습니다. – llamaoo7

0

한 번에 하나의 레코드를 쓰는 대신 일괄 처리 용량을 삽입하는 방법을 찾을 수 있습니까? 미친 DataSet 항목을 사용하지 않으려 고하지만, 먼저 모든 인서트를 로컬로 생성 한 다음 한 번 위로 올라가도록 만드는 방법이 아닙니까? 이 프로세스는 백그라운드에서 Excel을 엽니 다? 이러한 프로세스가 이후에 종료됩니까?

+0

편집 : 이 아니, 난 전혀 Excel을 사용하지 마십시오. Interop.Excel의 성능 저하로 인해 의도적으로 Interop.Excel을 피할 수 있습니다. – llamaoo7

1

다음은 몇 가지 아이디어입니다.

대상 통합 문서가 열려 있습니까? 위의 문서에서 확인되지는 않았지만 IIRC가 Jet 용 OLE DB 공급자에 실제로있는 버그 (Memory leak occurs when you query an open Excel worksheet by using ActiveX Data Objects)가 있습니다.

아무튼 대량 삽입물은 갈 길일 것 같습니다.

이렇게하려면 동일한 Jet OLE DB 공급자를 사용할 수 있습니다. 필요한 것은 하나의 행 테이블뿐입니다. 비행 중에도 조작 할 수 있습니다. 새 Excel 통합 문서를 만들려면 연결 문자열에 존재하지 않는 xls 파일을 사용하여 CREATE TABLE DDL을 실행하면 공급자가 워크 시트를 사용하여 통합 문서를 만들어 테이블을 나타냅니다.

CREATE TABLE [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable 
(
    x FLOAT 
); 

(더 나은 IMO Jet 데이터베이스 즉 .MDB 파일을 제작하는 것) :이를 실행할 수 있도록하여 Excel 통합 문서에 연결되어.여전히, 당신이가 당신의 가치의 파생 테이블 (DT1)을 만들 다음과 유사한 사용할 수 대상 통합 문서에 대한 연결을 사용하여, 다음

INSERT INTO [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable (x) 
    VALUES (0); 

:

사용 INSERT은 더미 행을 작성합니다 1 안타에 INSERT :

INSERT INTO MyExcelTable (key_col, data_col) 
SELECT DT1.key_col, DT1.data_col 
FROM (
    SELECT 22 AS key_col, 'abc' AS data_col 
    FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable 
    UNION ALL 
    SELECT 55 AS key_col, 'xyz' AS data_col 
    FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable 
    UNION ALL 
    SELECT 99 AS key_col, 'efg' AS data_col 
    FROM [EXCEL 8.0;DATABASE=C:\MyFabricatedWorkbook;HDR=YES].OneRowTable 
) AS DT1; 
+0

나는 당신이 제안하고있는 방법을 이해하고 있지만 왜 이런 식으로 메모리 사용 문제를 피할 수 있습니까? – llamaoo7

+0

"INSERT 쿼리를 실행하면 프로세스에서 사용하는 메모리가 계속 증가하는 것 같습니다."라고 말했기 때문에 실제로 INSERT 쿼리를 따르지 만 증상이 실제로 치료되지 않으면 최소한 증상을 최소화하십시오. – onedaywhen