将 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 |
+-------+--------------+--------------+------------+-----------------+
我有一个 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 |
+-------+--------------+--------------+------------+-----------------+