将XML文件水平导入SQL Server

时间:2015-08-26 03:45:51

标签: sql sql-server xml

我正在尝试将XML数据导入SQL服务器。我在下面找到了链接。

Import XML to SQL Server

我的要求略有不同,我需要创建表格,其中<name>为列名,<value>为列值。如下所示

XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:toatech:ResourceManagement:1.0">
   <SOAP-ENV:Body>
      <ns1:get_resources_list_response>
         <result_code>0</result_code>
         <resources>
            <resource>
               <properties>
                  <property>
                     <name>id</name>
                     <value>CAP_LOAD_TEST</value>
                  </property>
                  <property>
                     <name>status</name>
                     <value>inactive</value>
                  </property>
                  <property>
                     <name>parent_id</name>
                     <value>ABC_CO</value>
                  </property>
                  <property>
                     <name>type</name>
                     <value>GR</value>
                  </property>
                  <property>
                     <name>name</name>
                     <value>Capacity LoadTesting</value>
.
.
.
.

代码:

DECLARE @XmlFile XML

SELECT @XmlFile = BulkColumn  
FROM OPENROWSET(BULK 'C:\Users\GET_RESOURCE_LIST.xml', SINGLE_BLOB) x

SELECT 
    Resource_id = resource.value('(value)[1]', 'varchar(255)'),
    Resource_status = resource.value('(value)[2]', 'varchar(255)')
 FROM
@XmlFile.nodes('//resources/resource/properties/property') AS XTbl1(resource)

因此,当“资源”项重复时,它应该是表中具有新值集的新行

预期的表格输出:

    id              status      parent_id   type    name
    ==              ======      =========   ====    ====
    CAP_LOAD_TEST   inactive    ABC_CO      GR      Capacity LoadTesting

... 

使用上面的代码填充到一列的所有值。那就是问题。

1 个答案:

答案 0 :(得分:1)

您需要使用动态查询进行PIVOT操作:

DECLARE @xml XML = N'<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:toatech:ResourceManagement:1.0">
   <SOAP-ENV:Body>
      <ns1:get_resources_list_response>
         <result_code>0</result_code>
         <resources>
            <resource>
               <properties>
                  <property>
                     <name>id</name>
                     <value>CAP_LOAD_TEST</value>
                  </property>
                  <property>
                     <name>status</name>
                     <value>inactive</value>
                  </property>
                  <property>
                     <name>parent_id</name>
                     <value>ABC_CO</value>
                  </property>
                  <property>
                     <name>type</name>
                     <value>GR</value>
                  </property>
                  <property>
                     <name>name</name>
                     <value>Capacity LoadTesting</value>
                  </property>
                </properties>
             </resource>
             </resources>
    </ns1:get_resources_list_response>
            </SOAP-ENV:Body>
</SOAP-ENV:Envelope>'

DECLARE @Output nvarchar(max) = N''
DECLARE @PivotList nvarchar(max)


SELECT 
    @PivotList = COALESCE(@PivotList + ', ', N'') + N'[' + XC.value('./name[1]', 'varchar(255)') + N']'
FROM 
    @xml.nodes('//resources/resource[1]/properties/property') AS XT(XC)

SET @Output = N'SELECT 
    '+@PivotList+N'
FROM
(
    SELECT 
        Resource_id = resource.value(''(name)[1]'', ''varchar(255)''),
        Resource_status = resource.value(''(value)[1]'', ''varchar(255)''),
        unique_b_node = resource.value(''for $i in . return count(../../../*[. << $i]) + 1'', ''int'')
     FROM
    @xml.nodes(''//resources/resource/properties/property'') AS XTbl1(resource)
) AS s
PIVOT
(
    MAX(Resource_status)
    FOR Resource_id IN ('+@PivotList+N')
) AS t;'

EXEC sp_executesql @Output, N'@xml xml', @xml = @xml;