将 XML 转换为 SQL 列和值

Pivot XML into SQL Columns & values

我有一个 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 并按以下方式在 SQL 中填充 table。

换句话说,在rowid之后,将其余属性作为列,将它们的值作为列值。我正在使用以下代码将 rowid、属性及其值列为行。

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 之后的枢轴)可以完成吗?如果是,怎么做?

使用 XPath/XQuery 比使用 OPENXML 更好。查看 XML.nodes() and XML.value(). Check out some XPath guide online, 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            |
+-------+--------------+--------------+------------+-----------------+