2016-02-24 7 views
2

У меня есть XML-файл в следующем формате. Не каждое имя поля будет иметь значение. Каждое поле, за исключением поля id, будет varchar (40).Pivot XML в SQL Columns & values ​​

<index> 
    <doc id="0"> 
    <field name="MFG"> 
     <val>ACME</val> 
    </field> 
    <field name="InternalCode"> 
     <val /> 
    </field> 
    <field name="partnumber"> 
     <val>-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 следующим образом.

Desired Output from OPENXML

Другими словами, после 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)? Если да, то как?

ответ

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>-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   |    |-00 | PIN    | 
|  1 |    | ABCDE  | 919-555-7Z | WASHER   | 
|  2 | YOUR COMPANY |    | 131415  | BOLT   | 
+-------+--------------+--------------+------------+-----------------+