2012-10-08 3 views
1

XML 파일에서 MySQL 테이블로 데이터를 전송하는 가장 빠른 솔루션이 필요합니다. 나는 다음과 같이 내부에 여러 테이블과 XML 파일이 : XML to C#

<?xml version="1.0" standalone="yes"?> 
<RawData xmlns=""> 
    <Table1> 
    <ID_Table1>1</ID_Table1> 
    <Name>Victor</Name> 
    </Table1> 
    <Table2> 
    <ID_Table2>1</ID_Table2> 
    <Quantity>10</Quantity> 
    </Table2> 
</RawData> 

및 VS2010 내

, 난 표 1 및 표 2에 대한 MySQL의 DB를에서 DataTables 및 TableAdapters와 데이터 소스가 있습니다. 데이터 유형 내가 예외가 다른 경우 데이터 소스에 ( 1 :

myDSDataSet eDS = (myDSDataSet)this.FindResource("myDS"); // Declared in XAML 

OpenFileDialog dlg = new OpenFileDialog(); 
dlg.Filter = "XML Files|*.xml"; 
dlg.Title = "Select a XML File"; 

Nullable<bool> result = dlg.ShowDialog(); 

if (result == true) 
{     
mt1TableAdapter mt1_TA = new mt1TableAdapter(); 
mt2TableAdapter mt2_TA = new mt2TableAdapter(); 
manager = new TableAdapterManager();  

xmlDS = new DataSet(); 
dt = null; 

try 
{      
    xmlDS.ReadXml(dlg.FileName,XmlReadMode.InferTypedSchema); 

    for (int i = 0; i < xmlDS.Tables.Count; i++) 
    {       
    dt = xmlDS.Tables[i].Copy(); 

    eDS.Tables[eDS.Tables.IndexOf(xmlDS.Tables[i].TableName)].Merge(dt);       
    } 

    mt1_TA.Update(eDS.mt1); 
    mt2_TA.Update(eDS.mt2); 

    MessageBox.Show("Loading complete."); 
} 
catch (Exception error) 
{ 
    MessageBox.Show("ERROR: " + error.Message); 
}    
} 

을하지만 난이 큰 문제를 가지고이 코드를 실행 한 후 : 내 목표는 XML 파일을 읽고이 이러한 DataTables에 직접 데이터를 전달하는 것이 었습니다 필드는 DateTime이고 XML 필드는 문자열로 읽습니다.) 2. TableAdapter.Update() 호출은 데이터를 db에 저장하는 데 오랜 시간이 걸립니다 (15k 행은 10-15 분 소요)

그래서 ... 내 질문은 Can입니다. 누군가 나에게이 두 가지 문제를 해결하거나 mysql에 XML 데이터를 저장하는 가장 빠르고 최상의 방법이 무엇인지에 대한 지침을 알려주십시오.

참고 : - VS2010 및 MySQL 5.1을 사용하고 있습니다. - XML ​​파일을 외부 소스에서로드해야합니다. - XML에는 xmlns가 있지만 단순화를 위해 여기서는 생략되었습니다. - MySQL을 5.6으로 업그레이드하고 LOAD XML을 사용했지만 저장 프로 시저 내에서이 명령을 사용할 수 없습니다.

감사합니다.

답변

1

좋아,이 문제를 해결했습니다. 다른 사람이이 문제를 우연히 만났을 때를 대비하여 여기에 게시하십시오. 다음 솔루션은 테이블 구조에 사전 정의 된 스키마를 사용하고 데이터 처리를 위해 BackGroundWorker를 사용합니다. Idea는 StringBuilder (거대한 문자열을 생성하는 가장 빠른 방법)를 사용하여 새로 읽은 데이터를 MySQL 테이블에 입력하는 것이 었습니다. StringBuilder 변수는 모든 SQL 표현식을 사용하고 DB에서 단일 "실행"(많은 처리 시간 단축)으로 실행됩니다. 결국

StringBuilder sqlCommand = new StringBuilder(); 

DataSet xmlDS = new DataSet(); 

try 
{ 
    xmlDS.ReadXmlSchema(shemaPath); 
    xmlDS.ReadXml(dlg.FileName, XmlReadMode.ReadSchema);   

    sqlCommand.Clear(); 
    sqlCommand.Append("START TRANSACTION;"); 

    for (int i = xmlDS.Tables.Count-1; i >= 0; i--) 
    { 
     if (xmlDS.Tables[i].Rows.Count > 0) 
      sqlCommand.Append("DELETE FROM " + xmlDS.Tables[i].TableName + "; "); 
    } 

    int brojacDataTable = 0;    

    foreach (DataTable dataTable in xmlDS.Tables) 
    { 
     brojacDataTable++; 
     if (dataTable.Rows.Count > 0) 
     {  
      sqlCommand.Append(" INSERT INTO " + dataTable.TableName + " VALUES"); 

      int brojacDataRows = 0; 
      foreach (DataRow dataRow in dataTable.Rows) 
      { 
      brojacDataRows++; 
      sqlCommand.Append("("); 

      for (int i = 0; i < dataRow.ItemArray.Length; i++) 
      { 
       if (!System.DBNull.Value.Equals(dataRow.ItemArray[i])) 
       { 
        if (dataRow.ItemArray[i] is System.DateTime) sqlCommand.Append("'" +((DateTime)dataRow.ItemArray[i]).ToString("yyyy-MM-dd") + "'"); 
        else sqlCommand.Append("'" + dataRow.ItemArray[i].ToString() + "'"); 
       } 
       else sqlCommand.Append("null"); 

       if (i < dataRow.ItemArray.Length - 1) sqlCommand.Append(","); 
      } 

      if (brojacDataRows < dataTable.Rows.Count) sqlCommand.Append("),"); 
      else sqlCommand.Append(");"); 
      } 
     } 
    } 

    sqlCommand.Append("COMMIT;"); 

, 일부 테스트 후, 200.000+ 기록과 함께 약 30 테이블을 업로드하는 총 시간 20초보다 작은 : D