如何使用 Oracle 11g 中的 XMLAGG 函数序列化树数据而不是重复的 XML 标记,嵌套结构?

Posted

技术标签:

【中文标题】如何使用 Oracle 11g 中的 XMLAGG 函数序列化树数据而不是重复的 XML 标记,嵌套结构?【英文标题】:How serialize tree data with XMLAGG function in Oracle 11g not duplicate XML tags, with nested struct? 【发布时间】:2020-05-18 23:39:42 【问题描述】:

我有以下类型的树数据:1 个主题、2 个护照、2 个地址,这是一个实体。 如何使用嵌套的 xml 标签序列化为 xml 树数据?数据类型:

当我使用 XMLAGG 在 clob 中构建 xml 时,我得到了这样的带有重复标签的结构 示例:

<xml>
<person>
<title></title>
<document1></document1>
<document2></document2>
<adress1></adress1>
<adress2></adress2>
<adress1></adress1>
<phone1></phone1>
<phone2></phone2>
<phone3></phone3>
<phone1></phone1>
<phone2></phone2>
<phone3></phone3>
</person>
</xml> 

这是我在 CLOB 中构建 XML 的查询:

    ---XMLPERSOM
SELECT XMLELEMENT ("Person",
       XMLELEMENT ("ReferenceCode", SBS.ReferenceCode),
       XMLELEMENT ("LastName", SBS.LastName),
       XMLELEMENT ("FirstName", SBS.FirstName),
       XMLELEMENT ("MiddleName", SBS.MiddleName),
       XMLELEMENT ("BirthDate", SBS.BirthDate),
       XMLELEMENT ("BirthPlace", SBS.BirthPlace),
       XMLELEMENT ("sourceCode", SBS.sourceCode),
       XMLELEMENT ("GroupCode", SBS.GroupCode),
--XMLDOCUMENTS       
       XMLELEMENT ("Documents",  
       XMLAGG(
       XMLELEMENT ("Document",
       XMLELEMENT ("Type", DCS.Type),
       XMLELEMENT ("Series", DCS.Series),
       XMLELEMENT ("Number", DCS.NumberID),
       XMLELEMENT ("IssueDate", DCS.IssueDate),
       XMLELEMENT ("IssueAuthority", DCS.IssueAuthority)))),

       XMLELEMENT ("Addresses",
       XMLAGG(
       XMLELEMENT ("Address",
       XMLELEMENT ("Type", ADDS.Type),
       XMLELEMENT ("Location", ADDS.Location),
       XMLELEMENT ("Street", ADDS.Street),
       XMLELEMENT ("PostalCode", ADDS.PostalCode),
       XMLELEMENT ("Country", ADDS.RU),
       XMLELEMENT ("Region", ADDS.Region)))), 
       )      

FROM SUBJECT_SEGMENT SBS
LEFT JOIN DOCUMENT_SEGMENT DCS ON SBS.ID = DCS.SUBJECT_ID
LEFT JOIN ADDRESS_SEGMENT ADDS ON SBS.ID = ADDS.SUBJECT_ID
GROUP BY SBS.ReferenceCode, 
         SBS.LastName, 
         SBS.FirstName, 
         SBS.MiddleName, 
         SBS.BirthDate, 
         SBS.BirthPlace,
         SBS.sourceCode,
         SBS.GroupCode

因此,我有重复的标签或重复的 clob xml。我需要一个 clob 并且没有重复的标签。 感谢帮助!

【问题讨论】:

【参考方案1】:

如果某人有三个文档和两个地址,则您的查询会为此人生成 6 行。这就是价值观重复的原因。例如,您可以使用文档、地址和电话的相关子查询来解决它,如下所示:

SELECT XMLELEMENT ("Person", 
         XMLELEMENT ("ReferenceCode", ReferenceCode), 
         XMLELEMENT ("LastName", LastName),
         XMLELEMENT ("Documents",  
           (select XMLAGG(XMLELEMENT ("Document", XMLELEMENT ("Type", Type), 
                                                  XMLELEMENT ("Number", NumberID)))  
             from doc where referencecode = sbs.referencecode)),
         XMLELEMENT ("Addresses", 
           (select XMLAGG(XMLELEMENT ("Address", XMLELEMENT ("Street", Street))) 
             from adr where referencecode = sbs.referencecode)))
  FROM SBS

dbfiddle demo

【讨论】:

谢谢,我的朋友!您的相关子查询确实有效! Erlier 我尝试实现相关子查询,但我的尝试没有成功。我想,我在工作中感到厌倦)我暗示这是在施工时提供额外的“CTE”。希望您的回答对 StackOwerflow 的其他成员有所帮助!

以上是关于如何使用 Oracle 11g 中的 XMLAGG 函数序列化树数据而不是重复的 XML 标记,嵌套结构?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE,XMLAGG(arg),空 arg

oracle聚合函数XMLAGG用法简介

oracle行转列,列转行函数的使用(listagg,xmlagg)

使用 xmlagg 函数的 SQL 多 SELECT 查询 - 未以所需方式提取数据

Oracle 11g 中的限制子句

Oracle 11g 中的合并错误