将数据从 XML 导入 SQL Server 表

Posted

技术标签:

【中文标题】将数据从 XML 导入 SQL Server 表【英文标题】:Import data from XML to SQL Server tables 【发布时间】:2013-09-08 22:17:22 【问题描述】:

我在将数据从 xml 导入 SQL Server 表时遇到问题。

我的 XML 文件的这个例子:

<ORDER>
  <ORDER_HEADER>
    <NUMBER>109</NUMBER>
  </ORDER_HEADER>
  <CUSTOMER_HEADER>
    <CUSTOMER>Michael</CUSTOMER>    
  </CUSTOMER_HEADER>
  <ORDER_ITEMS>
    <ITEM>
      <CATALOG_NUMBER>2</CATALOG_NUMBER>
      <VAT>21</VAT>
    </ITEM>
    <ITEM>
      <CATALOG_NUMBER>5</CATALOG_NUMBER>
      <VAT>21</VAT>
    </ITEM>
    <ITEM>
      <CATALOG_NUMBER>7</CATALOG_NUMBER>
      <VAT>21</VAT>
    </ITEM>
    <ITEM>
      <CATALOG_NUMBER>9</CATALOG_NUMBER>
      <VAT>21</VAT>
    </ITEM>
  </ORDER_ITEMS>
</ORDER>

这是我的 C# 代码:

XDocument doc = XDocument.Load("C:\\Users\\L\\order.xml");
var NUMBER = doc.Descendants("NUMBER");                
var CUSTOMER = doc.Descendants("CUSTOMER");
var CATALOG_NUMBER = doc.Descendants("CATALOG_NUMBER");
var VAT = doc.Descendants("VAT");

SqlConnection conn = new SqlConnection("*****");
   conn.Open();
      foreach (var cislo in NUMBER)
        
          using (SqlCommand cmd = conn.CreateCommand())
            
               cmd.CommandText="Insert INTO ORDER_HEADER(NUMBER) VALUES (@cislo);";
               cmd.Parameters.AddWithValue("@cislo",cislo.Value);
               cmd.ExecuteNonQuery();
               cmd.Clone();
             
        
      foreach (var zakaznik in CUSTOMER)
        
           using (SqlCommand cmd = conn.CreateCommand())
             
               cmd.CommandText="Insert INTO CUSTOMER_HEAD(CUSTOMER)VALUES(@zakaznik);";
               cmd.Parameters.AddWithValue("@zakaznik", zakaznik.Value);
               cmd.ExecuteNonQuery();
               cmd.Clone();
              
        
      foreach (var katalo_cislo in CATALOG_NUMBER)
        foreach (var vat1 in VAT)
           
              using (SqlCommand cmd = conn.CreateCommand())
                 
                    cmd.CommandText = "Insert INTO ITEM (CATALOG_NUMBER,VAT) VALUES (@katalo_cislo,@vat1);";
                    cmd.Parameters.AddWithValue("@katalo_cislo", katalo_cislo.Value);
                    cmd.Parameters.AddWithValue("@vat1", vat1.Value);
                    cmd.ExecuteNonQuery();
                    cmd.Clone();
                  
           
    conn.Close();

但是前 2 个 sql 表是可以的,但是在最后一个 sql 表中,ITEM 超过 4 条记录...问题可能在两个 FOREACH 中...但是我如何从ORDER_ITEMS 加载记录?

谢谢

这是我的代码,现在包含我的所有值: ¨

var Items = doc.Descendants("ITEM").Select(x => new  NUMBER = (int?)x.Element("NUMBER"), CATALOG_NUMBER = (string)x.Element("CATALOG_NUMBER"), ITEM_NAME = (string)x.Element("ITEM_NAME"), UNIT = (string)x.Element("UNIT"), AMOUNT = (int?)x.Element("AMOUNT"), PRICE_WITHOUT_VAT = (string)x.Element("PRICE_WITHOUT_VAT"), VAT = (string)x.Element("VAT"), PRICE_VAT = (string)x.Element("PRICE_VAT"), EAN = (string)x.Element("EAN"), SUPPLIER_ITEM_NUMBER = (string)x.Element("SUPPLIER_ITEM_NUMBER"), SUPPLIER_ID = (string)x.Element("SUPPLIER_ID"), SUPPLIER_NAME = (string)x.Element("SUPPLIER_NAME"), ORDER_ITEMS_Id = (string)x.Element("ORDER_ITEMS_Id"), ).ToList();
                foreach (var item in Items)
                                            
                                                using (SqlCommand cmd = conn.CreateCommand())
                                                
                                                    cmd.CommandText = "Insert INTO ITEM (NUMBER,CATALOG_NUMBER,ITEM_NAME,UNIT,AMOUNT,PRICE_WITHOUT_VAT,VAT,PRICE_VAT,EAN,SUPPLIER_ITEM_NUMBER,SUPPLIER_ID,SUPPLIER_NAME,ORDER_ITEMS_Id) VALUES (@cislo,@katalo_cislo,@nazev_zbozi,@jednotka,@mnozstvi,@cenabezvat,@vat1,@cenavat,@ean1,@dodav_cislo,@dodav_id,@dodav_jmeno,@objednavkaid);";
                                                    cmd.Parameters.AddWithValue("@cislo", item.NUMBER);
                                                    cmd.Parameters.AddWithValue("@katalo_cislo", item.CATALOG_NUMBER);
                                                    cmd.Parameters.AddWithValue("@nazev_zbozi", item.ITEM_NAME);
                                                    cmd.Parameters.AddWithValue("@jednotka", item.UNIT);
                                                    cmd.Parameters.AddWithValue("@mnozstvi", item.AMOUNT);
                                                    cmd.Parameters.AddWithValue("@cenabezvat", item.PRICE_WITHOUT_VAT);
                                                    cmd.Parameters.AddWithValue("@vat1", item.VAT);
                                                    cmd.Parameters.AddWithValue("@cenavat", item.PRICE_VAT);
                                                    cmd.Parameters.AddWithValue("@ean1", item.EAN);
                                                    cmd.Parameters.AddWithValue("@dodav_cislo", item.SUPPLIER_ITEM_NUMBER);
                                                    cmd.Parameters.AddWithValue("@dodav_id", item.SUPPLIER_ID);
                                                    cmd.Parameters.AddWithValue("@dodav_jmeno", item.SUPPLIER_NAME);
                                                    cmd.Parameters.AddWithValue("@objednavkaid", item.ORDER_ITEMS_Id);
                                                    cmd.ExecuteNonQuery();
                                                    //cmd.Clone();
                                                
                                            

【问题讨论】:

您可以从您的 xml DataSet ds = new DataSet(); ds.ReadXml(XDocument.Load(fname).CreateReader()); 创建一个数据集,然后使用 SqlDataAdapter 将其直接插入数据库。 【参考方案1】:
foreach (var katalo_cislo in CATALOG_NUMBER)
foreach (var vat1 in VAT)

上面的代码会将(no of CATALOG_NUMBER)* (no of VAT) 记录插入数据库,我认为您需要将项目插入项目表。然后您可以简单地选择ITEM 节点并将它们插入到如下表中

var Items = doc.Descendants("ITEM")
        .Select(x=> new CATALOG_NUMBER= (string)x.Element("CATALOG_NUMBER"), 
                        VAT = (int?)x.Element("VAT") ).ToList();
foreach( var item in Items)

    using (SqlCommand cmd = conn.CreateCommand())
    
        cmd.CommandText = "Insert INTO ITEM (CATALOG_NUMBER,VAT) VALUES (@katalo_cislo,@vat1);";
        cmd.Parameters.AddWithValue("@katalo_cislo", item.CATALOG_NUMBER);
        cmd.Parameters.AddWithValue("@vat1", (object)item.VAT??DBNull.Value);
        cmd.ExecuteNonQuery();
    

【讨论】:

现在我有这个错误:元素的值不能为NULL...:/ @Kate 在您的 xml 中为一件商品没有增值税值。所以上面的代码会为此插入空值,如果vat为空,你到底想做什么? 对不起,请说明您的要求 我只想获取 od CATALOG_NUMBEr 和 VAT 的值并提供给 sql 表......但是当我有更多的 foreach 时,我有一个记录......而且我想要当我有 4 个 XML 项目时SQL 表中的文件 4 记录...对不起我的英语不好.. @Kate 你还有同样的错误吗?如果您遇到错误,您需要在数据库表中的增值税列中允许为空

以上是关于将数据从 XML 导入 SQL Server 表的主要内容,如果未能解决你的问题,请参考以下文章

将大型 XML 导入 SQL-Server 表的最快方法

将xml文件导入sql server表

如何将带有 xml 后代的 XElement 导入 SQL Server

将数据从 XML 文件导入 SQL 数据库

如何从 sql server 将数据导入 mongodb?

将数据从 Access 导入 SQL Server 的正确方法?