将XML拆分为行(TSQL)

时间:2017-07-06 21:37:11

标签: tsql

我已经和我搏斗了好几个小时,我完全不知道为什么它不能正常工作。我将以下XML作为单个列(以这种方式存储了几十条记录)。

<dsMQ1License xmlns="http://tempuri.org/dsMQ1License.xsd">
  <licenseModuleInfo>
    <module>AP</module>
    <status>1</status>
    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>
  </licenseModuleInfo>
  <licenseModuleInfo>
    <module>AU</module>
    <status>1</status>
    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>
  </licenseModuleInfo>
  <licenseModuleInfo>
    <module>CO</module>
    <status>1</status>
    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>
  </licenseModuleInfo>
  <licenseModuleInfo>
    <module>DO</module>
    <status>1</status>
    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>
  </licenseModuleInfo>
.
.
.
</dsMQ1License>

我希望能够获取XML列,并将其转换为每列代表最内层元素的行。

+--------+--------+---------------+
| Module | Status | StatusEndDate |
+--------+--------+---------------+
| AD     |      1 | 2017-12-28    |
| AU     |      1 | 2017-12-28    |
| CO     |      1 | 2017-12-28    |
| DO     |      1 | 2017-12-28    |
+--------+--------+---------------+

基于我到目前为止所阅读的所有内容,我觉得我所做的事情应该起作用。

SELECT 
T.C.value('(module)[1]','VARCHAR(MAX)') AS ModuleAbbr
,T.C.value('(status)[1]','bit') AS Active
FROM LicenseXML
CROSS APPLY LicenseXML.License.nodes('/dsMQ1License/licenseModuleInfo') T(C)

但它只返回0行。

我哪里错了?

2 个答案:

答案 0 :(得分:2)

试试这个

 DECLARE @x xml = '<dsMQ1License xmlns="http://tempuri.org/dsMQ1License.xsd">

  <licenseModuleInfo>

    <module>AP</module>

    <status>1</status>

    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>

  </licenseModuleInfo>

  <licenseModuleInfo>

    <module>AU</module>

    <status>1</status>

    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>

  </licenseModuleInfo>

  <licenseModuleInfo>

    <module>CO</module>

    <status>1</status>

    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>

  </licenseModuleInfo>

  <licenseModuleInfo>

    <module>DO</module>

    <status>1</status>

    <statusEndDate>2007-12-28T00:00:00.0000000-05:00</statusEndDate>

  </licenseModuleInfo>

</dsMQ1License>'



;WITH XMLNAMESPACES

(

DEFAULT 'http://tempuri.org/dsMQ1License.xsd' 

)

    SELECT 

    x.item.value('module[1]','VARCHAR(100)') AS ModuleAbbr

    ,x.item.value('status[1]','bit') AS Active

    ,x.item.value('statusEndDate[1]','datetime') AS EndDate

    FROM @x.nodes('//dsMQ1License/licenseModuleInfo') AS x(item)

答案 1 :(得分:0)

我正在使用WITH语句和一些子查询来实际查找许可证。最后,定义命名空间并使用命名空间别名是使其工作的原因。

WITH XMLNAMESPACES ('http://tempuri.org/dsMQ1License.xsd' AS ns)
,LicenseXML AS (
SELECT CAST(License AS XML) AS License
    FROM (
        SELECT a.i.value('.','varchar(max)') AS License
        FROM 
            (SELECT CAST(memLicense AS XML) memLicense FROM tblMQ1SysLicense) AS X
            CROSS APPLY X.memLicense.nodes('/License') AS a(i)
        ) AS LicXML
)
SELECT 
T.C.value('ns:module[1]','VARCHAR(MAX)') AS ModuleAbbr
,T.C.value('ns:status[1]','bit') AS Active
,T.C.value('ns:statusEndDate[1]','DATE') AS StatusDate
FROM LicenseXML
CROSS APPLY LicenseXML.License.nodes('/ns:dsMQ1License/ns:licenseModuleInfo') T(C)