拆分 XMLTYPE 以根据条件创建两个 XMLTYPE

Posted

技术标签:

【中文标题】拆分 XMLTYPE 以根据条件创建两个 XMLTYPE【英文标题】:Split XMLTYPE to Create two XMLTYPES based on conditions 【发布时间】:2014-09-05 16:45:47 【问题描述】:

我有一个 Oracle 表,其中包含存储在 XMLTYPE 中的多个 XML 文件。虽然我可以查询和更新 XML 类型,但我正在尝试编写一个过程,该过程将采用一个 XML 并根据某些条件将两个新 XMLTYPES 插入到同一个表中。

例如,如果以下内容存储在我的 XMLTYPE 中,我想创建两条消息,均包含所有标题信息,但一条包含排名/位置最多为 5 的消息行(将返回两行)和其他排名/位置大于 5(将返回三行):

<DistrictMsg timestamp="2014-09-05T04:45:00">
  <Publication xmlns:ns1="http://www.mynamespace.co.uk">
    <TopicID>ENGLISH_DISTRICTS</TopicID>
  </Publication>
  <Message xmlns="http://www.mynamespace.co.uk">
    <ns1:MessageHeader xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:MessageType>
        <ns1:ID>EnglishDistricts2014</ns1:ID>
      </ns1:MessageType>
      <ns1:DocType>
        <ns1:InternalName>
          <ns1:ID>DistrictByPopulation</ns1:ID>
        </ns1:InternalName>
      </ns1:DocType>
    </ns1:MessageHeader>
    <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:District>
        <ns1:Name>Birmingham</ns1:Name>
      </ns1:District>
      <ns1:Population measure="1000">1074.3</ns1:Population>
      <DistRank>
        <PopulationRank>
            <Position>1</Position>
        </PopulationRank>
      </DistRank>
    </ns1:MessageLine>
    <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:District>
        <ns1:Name>Manchester</ns1:Name>
      </ns1:District>
      <ns1:Population measure="1000">502.9</ns1:Population>
      <DistRank>
        <PopulationRank>
            <Position>7</Position>
        </PopulationRank>
      </DistRank>
    </ns1:MessageLine>
    <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:District>
        <ns1:Name>Liverpool</ns1:Name>
      </ns1:District>
      <ns1:Population measure="1000">465.7</ns1:Population>
      <DistRank>
        <PopulationRank>
            <Position>9</Position>
        </PopulationRank>
      </DistRank>
    </ns1:MessageLine>
    <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:District>
        <ns1:Name>Doncaster</ns1:Name>
      </ns1:District>
      <ns1:Population measure="1000">302.5</ns1:Population>
      <DistRank>
        <PopulationRank>
            <Position>34</Position>
        </PopulationRank>
      </DistRank>
    </ns1:MessageLine>
    <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
      <ns1:District>
        <ns1:Name>Cornwall</ns1:Name>
      </ns1:District>
      <ns1:Population measure="1000">533.8</ns1:Population>
      <DistRank>
        <PopulationRank>
            <Position>4</Position>
        </PopulationRank>
      </DistRank>      
    </ns1:MessageLine>
  </Message>
</DistrictMsg>

【问题讨论】:

【参考方案1】:

您可以通过使用 deletexml 删除不需要的条目来做到这一点。要返回不超过 5 的条目,我已经删除了所有大于 5 的条目。同样,要返回大于 5 的条目,我已经删除了小于或等于 5 的条目。 这是我的解决方案,希望对您有所帮助:

            with xml_data as(
            select xmltype('
            <DistrictMsg timestamp="2014-09-05T04:45:00">
              <Publication xmlns:ns1="http://www.mynamespace.co.uk">
                <TopicID>ENGLISH_DISTRICTS</TopicID>
              </Publication>
              <Message xmlns="http://www.mynamespace.co.uk">
                <ns1:MessageHeader xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:MessageType>
                    <ns1:ID>EnglishDistricts2014</ns1:ID>
                  </ns1:MessageType>
                  <ns1:DocType>
                    <ns1:InternalName>
                      <ns1:ID>DistrictByPopulation</ns1:ID>
                    </ns1:InternalName>
                  </ns1:DocType>
                </ns1:MessageHeader>
                <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:District>
                    <ns1:Name>Birmingham</ns1:Name>
                  </ns1:District>
                  <ns1:Population measure="1000">1074.3</ns1:Population>
                  <DistRank>
                    <PopulationRank>
                        <Position>1</Position>
                    </PopulationRank>
                  </DistRank>
                </ns1:MessageLine>
                <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:District>
                    <ns1:Name>Manchester</ns1:Name>
                  </ns1:District>
                  <ns1:Population measure="1000">502.9</ns1:Population>
                  <DistRank>
                    <PopulationRank>
                        <Position>7</Position>
                    </PopulationRank>
                  </DistRank>
                </ns1:MessageLine>
                <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:District>
                    <ns1:Name>Liverpool</ns1:Name>
                  </ns1:District>
                  <ns1:Population measure="1000">465.7</ns1:Population>
                  <DistRank>
                    <PopulationRank>
                        <Position>9</Position>
                    </PopulationRank>
                  </DistRank>
                </ns1:MessageLine>
                <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:District>
                    <ns1:Name>Doncaster</ns1:Name>
                  </ns1:District>
                  <ns1:Population measure="1000">302.5</ns1:Population>
                  <DistRank>
                    <PopulationRank>
                        <Position>34</Position>
                    </PopulationRank>
                  </DistRank>
                </ns1:MessageLine>
                <ns1:MessageLine xmlns:ns1="http://www.mynamespace.co.uk">
                  <ns1:District>
                    <ns1:Name>Cornwall</ns1:Name>
                  </ns1:District>
                  <ns1:Population measure="1000">533.8</ns1:Population>
                  <DistRank>
                    <PopulationRank>
                        <Position>4</Position>
                    </PopulationRank>
                  </DistRank>      
                </ns1:MessageLine>
              </Message>
            </DistrictMsg>') xtype
            from dual)
            select 
            xmlserialize(document 
            deletexml(xtype, '//ns1:MessageLine[ns1:DistRank/ns1:PopulationRank/ns1:Position[text()>5]]', 'xmlns:ns1="http://www.mynamespace.co.uk"')  
            as clob indent size = 2) up_to_five,
            xmlserialize(document 
            deletexml(xtype, '//ns1:MessageLine[ns1:DistRank/ns1:PopulationRank/ns1:Position[text()<=5]]', 'xmlns:ns1="http://www.mynamespace.co.uk"')  
            as clob indent size = 2) greater_than_five
            from xml_data;

【讨论】:

以上是关于拆分 XMLTYPE 以根据条件创建两个 XMLTYPE的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能通过 DBLink 发送 Oracle XMLType?

sqlserver table partion

根据开始和结束索引(保存在两个向量中)并使用条件将 data.frame 拆分为较小的 data.frame

SSIS 多个条件拆分

如何根据 Oracle SQL 中的某些条件将列拆分为 2?

数着没有。在给定拆分原始列表的条件下,来自两个列表的匹配项