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中,我有来自MySql db的DataSource和Table1和Table2的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 分钟)

所以......我的问题是,有人可以帮我解决这两个问题,或者给我一些指导,什么是将 XML 数据保存到 mysql 的最快和最好的方法。

注意: - 我使用的是 VS2010 和 MySQL 5.1。- XML 文件需要从外部源加载。- XML 有其 xmlns,但为简单起见,此处省略。- 我尝试将 MySQL 升级到 5.6 并使用 LOAD XML,但我无法在存储过程中使用此命令。

谢谢

4

1 回答 1

1

好的,我已经解决了这个问题。在这里发布以防其他人遇到此问题。以下解决方案使用预定义模式的表结构和 BackGroundWorker 进行数据处理。想法是使用 StringBuilder(生成大字符串的最快方法)将新读取的数据输入到 MySQL 表中。StringBuilder 变量采用所有 sql 表达式并在 DB 上以单个“go”执行(大大减少了处理时间!)。

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

最后,经过一些测试,上传大约 30 个包含 200.000 多条记录的表的总时间不到 20 秒:D

于 2012-10-16T07:58:06.303 回答