将XML转换为SQL列和&值

时间:2016-02-24 20:49:14

标签: sql-server xml pivot

我有一个以下格式的XML文件。并非每个字段名都有值。除了id字段之外的每个字段都是varchar(40)。

<index>
  <doc id="0">
    <field name="MFG">
      <val>ACME</val>
    </field>
    <field name="InternalCode">
      <val />
    </field>
    <field name="partnumber">
      <val>012345-00</val>
    </field>
    <field name="partdescription">
      <val>PIN</val>
    </field>
  </doc>
  <doc id="1">
    <field name="MFG">
      <val />
    </field>
    <field name="InternalCode">
      <val>ABCDE</val>
    </field>
    <field name="partnumber">
      <val>919-555-7Z</val>
    </field>    
    <field name="partdescription">
      <val>WASHER</val>
    </field>
  </doc>
  <doc id="2">
    <field name="MFG">
      <val>YOUR COMPANY</val>
    </field>
    <field name="InternalCode">
      <val />
    </field>
    <field name="partnumber">
      <val>131415</val>
    </field>
    <field name="partdescription">
      <val>BOLT</val>
    </field>
  </doc>
</index>

我想要做的是阅读XML&amp;以下列方式在SQL中填充表。

Desired Output from OPENXML

换句话说,在rowid之后,将其余属性作为列及其值作为列值进行旋转。我正在使用以下代码列出rowid,attribute&amp;它们的值为行。

SELECT  XMLAttribute.rowid, XMLAttribute.name, XMLAttribute.val
FROM OPENXML (@hdoc, 'index/doc/field', 2 ) 
        WITH (rowid int '../@id',
        name       VARCHAR(128) '@name',
        val varchar(128) 'val'                  
            ) AS XMLAttribute

这可以(在rowid之后转动)完成吗?如果是这样,怎么样?

1 个答案:

答案 0 :(得分:3)

使用XPath / XQuery比使用OPENXML更好。查看有关XML.nodes()XML.value()的文档。在线查看一些XPath指南,this是一个很好的指南。

DECLARE @i XML=
'<index>
<doc id="0"><field name="MFG"><val>ACME</val></field><field name="InternalCode"><val /></field><field name="partnumber"><val>012345-00</val></field><field name="partdescription"><val>PIN</val></field></doc>
<doc id="1"><field name="MFG"><val /></field><field name="InternalCode"><val>ABCDE</val></field><field name="partnumber"><val>919-555-7Z</val></field><field name="partdescription"><val>WASHER</val></field></doc>
<doc id="2"><field name="MFG"><val>YOUR COMPANY</val></field><field name="InternalCode"><val /></field><field name="partnumber"><val>131415</val></field><field name="partdescription"><val>BOLT</val></field></doc>
</index>';

SELECT
    rowid=n.v.value('@id','VARCHAR(40)'),
    MFG=n.v.value('(field[@name="MFG"]/val)[1]','VARCHAR(40)'),
    InternalCode=n.v.value('(field[@name="InternalCode"]/val)[1]','VARCHAR(40)'),
    partnumber=n.v.value('(field[@name="partnumber"]/val)[1]','VARCHAR(40)'),
    partdescription=n.v.value('(field[@name="partdescription"]/val)[1]','VARCHAR(40)')
FROM
    @i.nodes('/index/doc') AS n(v);

结果:

+-------+--------------+--------------+------------+-----------------+
| rowid |     MFG      | InternalCode | partnumber | partdescription |
+-------+--------------+--------------+------------+-----------------+
|     0 | ACME         |              | 012345-00  | PIN             |
|     1 |              | ABCDE        | 919-555-7Z | WASHER          |
|     2 | YOUR COMPANY |              | 131415     | BOLT            |
+-------+--------------+--------------+------------+-----------------+