将xml数据读取到格式化数据表

时间:2014-09-25 05:33:20

标签: sql sql-server xml sql-server-2008 sql-server-2012

请帮我读一下这个XML数据

<project id="1">

    <entity id="1">
        <subproject id="1">
            <jobplan id="1">
                <activity id="1">
                    <task id="1"/>
                    <task id="2"/>
                </activity>
            </jobplan>
        </subproject>
    </entity>

    <entity id="2">
        <jobplan id="2">
            <activity id="2">
                <task id="3"/>
            </activity>
        </jobplan>
    </entity>

    <subproject id="2">
        <jobplan id="3">
            <activity id="3">
                <task id="4"/>
            </activity>
        </jobplan>
    </subproject>

    <jobplan id="4">
        <activity id="4">
            <task id="5"/>
            <task id="6"/>
        </activity>
    </jobplan>

</project>

使用T-SQL不使用任何其他批量上传工具或任何第三方工具的下表格式。想想这个数据是在表列中,或者是从SP中获取XML类型参数的数据。

table format

2 个答案:

答案 0 :(得分:1)

select a.c.value('(../../../../../@id)[1]', 'int') as project
      ,a.c.value('(../../../../@id)[1]', 'int') as entity
      ,a.c.value('(../../../@id)[1]', 'int') as subproject
      ,a.c.value('(../../@id)[1]', 'int') as jobplan
      ,a.c.value('(../@id)[1]', 'int') as activity
      ,a.c.value('(@id)[1]', 'int') as task
from @xml.nodes('/project/..')t(c)   
cross apply t.c.nodes('project/entity/subproject/jobplan/activity/task') as a(c) 

UNION

select a.c.value('(../../../../@id)[1]', 'int') as project
      ,a.c.value('(../../../@id)[1]', 'int') as entity
      ,NULL as subproject
      ,a.c.value('(../../@id)[1]', 'int') as jobplan
      ,a.c.value('(../@id)[1]', 'int') as activity
      ,a.c.value('(@id)[1]', 'int') as task
from @xml.nodes('/project/..')t(c)   
cross apply t.c.nodes('project/entity/jobplan/activity/task') as a(c) 

UNION

select a.c.value('(../../../../@id)[1]', 'int') as project
      ,NULL as entity
      ,a.c.value('(../../../@id)[1]', 'int') as subproject
      ,a.c.value('(../../@id)[1]', 'int') as jobplan
      ,a.c.value('(../@id)[1]', 'int') as activity
      ,a.c.value('(@id)[1]', 'int') as task
from @xml.nodes('/project/..')t(c)   
cross apply t.c.nodes('project/subproject/jobplan/activity/task') as a(c) 

UNION  

select a.c.value('(../../../@id)[1]', 'int') as project
      ,NULL as entity
      ,NULL as subproject
      ,a.c.value('(../../@id)[1]', 'int') as jobplan
      ,a.c.value('(../@id)[1]', 'int') as activity
      ,a.c.value('(@id)[1]', 'int') as task
from @xml.nodes('/project/..')t(c)   
cross apply t.c.nodes('project/jobplan/activity/task') as a(c) 

答案 1 :(得分:0)

您可以在sql server中使用open xml功能来读取xml。

请参阅链接http://msdn.microsoft.com/en-us/library/ms186918.aspx

对于下面问题中的xml类型,是获得所需结果的方法。

declare @XmlString varchar(max)
set @XmlString='<Table><project id="1">
    <entity id="1">
        <subproject id="1">
            <jobplan id="1">
                <activity id="1">
                    <task id="1"/>
                    <task id="2"/>
                </activity>
            </jobplan>
        </subproject>
    </entity>
    <entity id="2">
        <jobplan id="2">
            <activity id="2">
                <task id="3"/>
            </activity>
        </jobplan>
    </entity>
    <subproject id="2">
        <jobplan id="3">
            <activity id="3">
                <task id="4"/>
            </activity>
        </jobplan>
    </subproject>
    <jobplan id="4">
        <activity id="4">
            <task id="5"/>
            <task id="6"/>
        </activity>
    </jobplan>
</project></Table>'

DECLARE @DocHandle int    
 EXEC sp_xml_preparedocument @DocHandle OUTPUT, @XmlString    


 SELECT *
 FROM OPENXML (@DocHandle, '/Table/project/entity/subproject/jobplan/activity/task',2)    
 WITH    
 (                    
 id int '../../../../../@id',    
 entity int '../../../../@id',    
 subproject int '../../../@id',  
 jobplan int '../../@id',    
 activity int '../@id',  
 task int '@id'
 )  
 union all
  SELECT *
 FROM OPENXML (@DocHandle, '/Table/project/entity/jobplan/activity/task',2)    
 WITH    
 (                    
 id int '../../../../@id',    
 entity int '../../../@id',    
 subproject int '@NA',  
 jobplan int '../../@id',    
 activity int '../@id',  
 task int '@id'
 )  
  union all
  SELECT *
 FROM OPENXML (@DocHandle, '/Table/project/subproject/jobplan/activity/task',2)    
 WITH    
 (                    
 id int '../../../../@id',    
 entity int '@NA',    
 subproject int '../../../@id',  
 jobplan int '../../@id',    
 activity int '../@id',  
 task int '@id'
 ) 
   union all
  SELECT *
 FROM OPENXML (@DocHandle, '/Table/project/jobplan/activity/task',2)    
 WITH    
 (                    
 id int '../../../@id',    
 entity int '@NA',    
 subproject int '@NA',  
 jobplan int '../../@id',    
 activity int '../@id',  
 task int '@id'
 ) 

 EXEC sp_xml_removedocument @DocHandle