SQL Server使用XMLQUERY解析XML Nodes数组。

问题描述 投票:0回答:1

我正试图解析一个XML Array的节点,这是一个nvarchar(max)列转换为XML,我已经用google搜索了,也搜索了stackoverflow,但我没有找到任何可能帮助我解决这个问题的例子。

我有一个存储为nvarchar(max)的XML值,格式如下。

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfCmnStatusRuleOverride xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cmnStatusRuleOverride xsi:type="cmnCoveredByOverride">
        <Start>2020-05-28T17:00:00</Start>
        <End>2020-05-29T07:00:00</End>
        <SuspendExpiration>0001-01-01T00:00:00</SuspendExpiration>
        <subID>103</subID>
        <listID>4016</listID>
        <Description>Jane Doe</Description>
    </cmnStatusRuleOverride>
    <cmnStatusRuleOverride xsi:type="cmnCoveredByOverride">
        <Start>2020-05-26T17:00:00</Start>
        <End>2020-05-28T07:00:00</End>
        <SuspendExpiration>0001-01-01T00:00:00</SuspendExpiration>
        <subID>103</subID>
        <listID>4014</listID>
        <Description>Joe Blow</Description>
    </cmnStatusRuleOverride>
    <cmnStatusRuleOverride xsi:type="cmnCoveredByOverride">
        <Start>2020-05-25T17:00:00</Start>
        <End>2020-05-26T07:00:00</End>
        <SuspendExpiration>0001-01-01T00:00:00</SuspendExpiration>
        <subID>103</subID>
        <listID>4016</listID>
        <Description>Jane Doe</Description>
    </cmnStatusRuleOverride>
</ArrayOfCmnStatusRuleOverride>

我使用下面的SQL来解析内容,这和我的需求很接近,但是交叉应用却给我带来了问题。

declare @Status xml, @Override nvarchar(100),@ORStart nvarchar(50), @OREnd nvarchar(50)
set @Status = 
(select b.Overrides from Database.dbo.Descriptions as a
inner join Database.dbo.Listings as b on a.listID = b.listId
inner join Database.dbo.Clients as c on b.subId = c.subId and cast(c.ClientNumber as nvarchar) = '2195956693'
--cross apply @Status.nodes('/ArrayOfCmnStatusRuleOverride/cmnStatusRuleOverride/Description') as T(Loc)
where a.Description = 'Jack Sprat')

select T.OVR.query('.') 'Override'--, T1.STT.query('.') 'Start'--, T2.ENND.query('.') 'End'
from Database.dbo.Descriptions as a
inner join Database.dbo.Listings as b on a.listID = b.listId
inner join Database.dbo.Clients as c on b.subId = c.subId and cast(c.ClientNumber as nvarchar) = '9876543210'
cross apply @Status.nodes('/ArrayOfCmnStatusRuleOverride/cmnStatusRuleOverride/Description') as T(OVR)
--cross apply T.OVR.nodes('/ArrayOfCmnStatusRuleOverride/cmnStatusRuleOverride/Start') as T1(STT)
--cross apply T.OVR.nodes('/ArrayOfCmnStatusRuleOverride/cmnStatusRuleOverride/End') as T2(ENND)
where a.Description = 'Jack Sprat'

将第二个和第三个xml查询注释掉,我得到3个结果,正如我所期望的那样。

  1. 无名氏
  2. Joe Blow
  3. 无名氏

如果我取消第二个查询,那么我得到9个结果,如下图所示

    Override        Start
  1. 无名氏 2020-05-28T17:00:00
  2. 无名氏 2020-05-26T17:00:00
  3. 无名氏 2020-05-25T17:00:00
  4. 乔布洛 2020-05-28T17:00:00
  5. 乔吹 2020-05-26T17:00:00
  6. 乔吹 2020-05-25T17:00:00
  7. 无名氏 2020-05-28T17:00:00
  8. 无名氏 2020-05-26T17:00:00
  9. 无名氏 2020-05-25T17:00:00

当然,如果我取消第三个查询,我得到的是27行。 有什么提示,我做错了什么? 我从昨天早上开始就一直在用这个方法想弄明白这个问题,就差那么一点,却又那么远。

arrays sql-server xmlnode qxmlquery
1个回答
0
投票

想出了它。

select T.OVR.query('./Description') 'Override', 
T.OVR.query('./Start') 'Start', 
T.OVR.query('./End') 'End'
from Database.dbo.Descriptions as a
inner join Database.dbo.Listings as b on a.listID = b.listId
inner join Database.dbo.Clients as c on b.subId = c.subId and cast(c.ClientNumber as nvarchar) = '9876543210'
cross apply @Status.nodes('/ArrayOfCmnStatusRuleOverride/cmnStatusRuleOverride') as T(OVR)
where a.Description = 'Jack Sprat'
© www.soinside.com 2019 - 2024. All rights reserved.