我有一个以下格式的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中填充表。
换句话说,在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之后转动)完成吗?如果是这样,怎么样?
答案 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 |
+-------+--------------+--------------+------------+-----------------+