1

XMLファイルからMySQLテーブルにデータを転送するための最速のソリューションが必要です。次のように、内部に複数のテーブルを含むXMLファイルがあります。

<?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内には、Table1とTable2用のMySqldbのDataTablesとTableAdaptersを含むデータソースがあります。私の目標は、XMLファイルを読み取り、そのデータを次の方法でこれらのDataTablesに直接渡すことでした。

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);
 }              
}

しかし、このコードを実行した後、2つの大きな問題が発生しました:1。データ型が異なる場合、例外が発生します(DataSourceフィールドはDateTimeで、XMLフィールドは文字列として読み取られます)2。TableAdapter.Update()を呼び出すと、データを保存するのに長い時間がかかりますdb(15k行は10〜15分かかります)

だから...私の質問は、誰かが私がこれらの2つの問題を解決するのを手伝ってくれるか、XMLデータをmysqlに保存するための最速で最良の方法について教えてくれませんか。

注:-私はVS2010とMySQL5.1を使用しています。-XMLファイルは外部ソースからロードする必要があります。--XMLにはxmlnsがありますが、簡単にするためにここでは省略しています。--MySQLを5.6にアップグレードしてLOADXMLを使用しようとしましたが、ストアドプロシージャ内でこのコマンドを使用できません。

ありがとう

4

1 に答える 1

1

わかりました、私はこの問題を解決しました。他の誰かがこの問題に遭遇した場合に備えて、ここに投稿してください。次のソリューションでは、テーブル構造に定義済みのスキーマを使用し、データ処理に BackGroundWorker を使用します。アイデアは、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

于 2012-10-16T07:58:06.303 に答える