【问题标题】:Import XML to SQL table and format data将 XML 导入 SQL 表并格式化数据
【发布时间】:2016-07-26 09:14:11
【问题描述】:

有人能帮助我吗?我正在尝试将 xml 文件导入到 sql server 表中。我可以导入所需的数据,但在获取所需格式时遇到了一些问题。

    declare @input XML = '<Sub>
    <Results>
    <Result>
      <ids>
        <id>
          <type>code</type>
          <value>9004a3d2</value>
        </id>
        <id>
          <type>username</type>
          <value>jbloggs001</value>
          <date>20160725</date>
        </id>
        <id>
         <type>EmployeeID</type>
         <value>01234</value>
         <date>20160725</date>
        </id>
     </ids>
    </Result>
</Results>
</Sub>'
   SELECT
     datatype = XCol.value('(type)[1]','varchar(25)'),
    datavalue = XCol.value('(value)[1]','varchar(50)')
   FROM 
      @input.nodes('/Sub/Results/Result/ids/id') AS XTbl(XCol)

这给出了 3 列,例如:

datatype       datavalue
--------------------------------
   code        9004a3d2   
   username    jbloggs001
   employeeID  01234

是否可以将其导入为?

EmployeeID   USername     Code
    ---------------------------------
   01234        jbloggs    0019004a3d2

谢谢

【问题讨论】:

标签: sql sql-server xml tsql


【解决方案1】:

正如 cmets 中建议的那样,可以使用 PIVOT 完成:

   SELECT *
   FROM (
   SELECT
     datatype = XCol.value('(type)[1]','varchar(25)'),
    datavalue = XCol.value('(value)[1]','varchar(50)')
   FROM 
      @input.nodes('/Sub/Results/Result/ids/id') AS XTbl(XCol)
    ) as p
    PIVOT (
        MAX(datavalue) FOR datatype IN (EmployeeID,username,code)
    ) as pvt

输出:

EmployeeID  username    code
01234       jbloggs001  9004a3d2

如果输入总是相同的types:

SELECT  XCol.value('(id/value)[3]','varchar(50)') as EmployeeID,
        XCol.value('(id/value)[2]','varchar(50)') as username,
        XCol.value('(id/value)[1]','varchar(50)') as code
FROM @input.nodes('/Sub/Results/Result/ids') AS XTbl(XCol)

【讨论】:

  • PIVOT 解决方案很好(我这边 +1),但我不会依赖 XML 中的排序顺序。使用 XML 的一个原因是在不破坏现有解决方案的情况下具有可扩展性。使用适当的 XQuery 获取节点要安全得多(请参阅我的答案...)
【解决方案2】:

另一个选项是 XQuery 包含函数

declare @input XML = '<Sub>
    <Results>
    <Result>
      <ids>
        <id>
          <type>code</type>
          <value>9004a3d2</value>
        </id>
        <id>
          <type>username</type>
          <value>jbloggs001</value>
          <date>20160725</date>
        </id>
        <id>
         <type>EmployeeID</type>
         <value>01234</value>
         <date>20160725</date>
        </id>
     </ids>
    </Result>
</Results>
</Sub>';
   SELECT
    code = XCol.value('(id[contains((./type)[1],"code")]/value)[1]','varchar(50)'),
    username = XCol.value('(id[contains((./type)[1],"username")]/value)[1]','varchar(50)'),
    EmployeeID = XCol.value('(id[contains((./type)[1],"EmployeeID")]/value)[1]','varchar(50)')

   FROM 
      @input.nodes('/Sub/Results/Result/ids') AS XTbl(XCol);

【讨论】:

    【解决方案3】:

    以下查询适用于您的解决方案

    Select [EmployeeID],[Username],[Code]
    FROM #TEMP
    PIVOT
    (
    MAX(DATAVALUE) FOR DATATYPE IN (code,username,employeeID)
    )A
    

    【讨论】:

      【解决方案4】:

      另一种非常直接且类型安全的方法是:

      SELECT id.value('(id[type="code"]/value)[1]','varchar(max)') AS code
            ,id.value('(id[type="username"]/value)[1]','varchar(max)') AS username
            ,id.value('(id[type="EmployeeID"]/value)[1]','varchar(max)') AS EmployeeID
      FROM @input.nodes('Sub/Results/Result/ids') AS A(id)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-16
        • 1970-01-01
        • 2013-09-08
        • 2016-05-11
        • 2021-10-26
        • 2010-10-17
        • 2022-07-13
        • 1970-01-01
        相关资源
        最近更新 更多