2012-10-24 5 views
3

SqlbulkCopy를 사용하여 SQL Server에 Excel 데이터를 가져 오려고하는데 문제는 중복 레코드가 입력되지 않도록하려는 것입니다. 복제본을 무시하거나 삭제할 수있는 방법이 있습니까?SqlBulkCopy를 사용하는 동안 중복 된 항목을 방지하는 방법?

protected void Button1_Click(object sender, EventArgs e) 
{ 
    string strFileType = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower(); 
    string strFileName = FileUpload1.PostedFile.FileName.ToString(); 

    FileUpload1.SaveAs(Server.MapPath("~/Import/" + strFileName + strFileType)); 
    string strNewPath = Server.MapPath("~/Import/" + strFileName + strFileType); 

    string excelConnectionString = String.Format(@"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + strNewPath + "; Extended Properties=Excel 8.0;"); 

    // Create Connection to Excel Workbook 
    using (OleDbConnection connection = new OleDbConnection(excelConnectionString)) 
    { 
     var command = new OleDbCommand("Select ID,Data FROM [Sheet1$]", connection); 

     connection.Open(); 

     // Create DbDataReader to Data Worksheet 
     using (DbDataReader dr = command.ExecuteReader()) 
     { 
      // SQL Server Connection String 
      string sqlConnectionString = "Data Source=ARBAAZ-1B14C081;Initial Catalog=abc;Integrated Security=True"; 

      con.Open(); 
      DataTable dt1 = new DataTable(); 
      string s = "select count(*) from ExcelTable"; 
      string r = ""; 
      SqlCommand cmd1 = new SqlCommand(s, con); 

      try 
      { 
       SqlDataAdapter da1 = new SqlDataAdapter(cmd1); 
       da1.Fill(dt1); 
      } 
      catch 
      { 
      } 

      int RecordCount; 
      RecordCount = Convert.ToInt32(cmd1.ExecuteScalar()); 
      r = RecordCount.ToString(); 
      Label1.Text = r; 
      con.Close(); 
      int prv = Convert.ToInt32(r); 

      // Bulk Copy to SQL Server 
      using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString)) 
      { 
       bulkCopy.DestinationTableName = "ExcelTable"; 

       SqlBulkCopyColumnMapping mapping1 = new SqlBulkCopyColumnMapping("excelid", "id"); 
       SqlBulkCopyColumnMapping mapping2 = new SqlBulkCopyColumnMapping("exceldata", "data"); 

       bulkCopy.ColumnMappings.Add(mapping1); 
       bulkCopy.ColumnMappings.Add(mapping2); 

       bulkCopy.WriteToServer(dr); 
      } 

      con.Open(); 

      DataTable dt = new DataTable(); 
      s = "select count(*) from ExcelTable"; 
      r = ""; 
      SqlCommand cmd = new SqlCommand(s, con); 

      try 
      { 
       SqlDataAdapter da = new SqlDataAdapter(cmd); 
       da.Fill(dt); 
      } 
      catch 
      { 
      } 

      RecordCount = Convert.ToInt32(cmd.ExecuteScalar()); 
      r = RecordCount.ToString(); 
      Label1.Text = r; 
      con.Close(); 
      int ltr = Convert.ToInt32(r); 

      if (prv == ltr) 
      { 
       Label1.Text = "No records Added"; 
      } 
      else 
      { 
       Label1.Text = "Records Added Successfully !"; 
      } 
     } 
    } 
} 

중복을 삭제하기위한 트리거를 생성하여이 문제를 해결할 수 있습니까? 그렇다면 어떻게? 나는 방아쇠를 만들지 않은 초보자입니다.

또 다른 문제는 내가 열 매핑을 작동시키지 못해도 상관 없습니다. Excel 시트 및 데이터베이스의 열 이름이 다른 경우 데이터를 업로드 할 수 없습니다.

답변

8

당신은 INDEX

CREATE UNIQUE INDEX MyIndex ON ExcelTable(id, data) WITH IGNORE_DUP_KEY 

를 만들 수 있습니다 그리고 당신은 dB로 대량 데이터를 삽입 할 때, 모든 중복 값을 삽입하지 않습니다.

+0

모든 필드에 색인이 필요하지 않습니까? – Diego

+0

오, 그는 ID와 데이터 만 가져오고 있습니다. :) 좋은 솔루텐이지만 중복 된 레코드가 실제로 테이블에 존재할 수 있다면 대량 프로세스에서 무시해야합니다. – Diego

+0

@ user1557976은 테이블에 두 개의 열만 있습니다 . – kmatyaszek

0

아니요, DB에로드 (DISTINCT 연산 실행)하기 전에 코드의 Dr 오브젝트에서 관리하거나 DB에서 트리거를 작성하여 확인하십시오. 트리거는 벌크 인서트의 성능을 감소시킵니다.

또 다른 옵션은 사용하여 임시 테이블에서 대상 테이블에 삽입 한 후 임시 테이블에 삽입 대량으로 일 것 선택 DISTINCT

0
가져올 때

는 지금까지 내가 기억하는, 당신은 중복 행을 필터링 할 수 엑셀 파일 자체에서.

다음 SQL 쿼리는 OleDbCommand 생성자에서 사용해야합니다.

var command = new OleDbCommand("Select DISTINCT ID,Data FROM [Sheet1$]", connection); 
관련 문제