PLSQLアプローチ:
SQL> create or replace function get_xml_doc(p_id Checkpoint_Data.checkpoint_id%type)
2 return xmltype deterministic
3 is
4 v_xml clob;
5 begin
6 for r_row in (select cd.checkpoint_data
7 from Checkpoint_Data cd
8 where cd.checkpoint_id = p_id
9 order by cd.sequence_number)
10 loop
11 v_xml := v_xml || r_row.checkpoint_data;
12 end loop;
13
14 return xmltype(v_xml);
15 end get_xml_doc;
16 /
Function created.
SQL>
SQL> select cp.checkpoint_id, get_xml_doc(cp.checkpoint_id) xml_doc
2 from checkpoint cp, transaction tr
3 where cp.location = 'someLocation'
4 and cp.trans_id = tr.trans_id
5 and tr.time <= sysdate
6 group by cp.checkpoint_id;
CHECKPOINT_ID XML_DOC
------------- ----------------------------------------
1 <root>
<a>1st node</a>
<b>2nd node</b>
<compType>
<a>foo</a>
</compType>
<d>another node</d>
</root>
または、PLSQLがオプションでない場合はSQLのみ:
たとえば、次のようCDATA
に使用できます。XMLAGG
SQL> select * from Checkpoint_Data;
CHECKPOINT_ID SEQUENCE_NUMBER CHECKPOINT_DATA
------------- --------------- --------------------------------------------------
1 1 <root><a>1st node</a><b>2nd node</b>
1 2 <compType><a>foo</a></compType><d>another node</d>
1 3 </root>
SQL> select c.xmlstr.transform(xmltype('<xsl:stylesheet version="1.0"
2 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
3 <xsl:output method="xml" omit-xml-declaration = "yes" version="1.0" />
4 <xsl:template match="/">
5 <xsl:for-each select="/root/nde">
6 <xsl:sort select="@seq"/>
7 <xsl:value-of select="." disable-output-escaping="yes" />
8 </xsl:for-each>
9 </xsl:template>
10 </xsl:stylesheet>')) xml
11 from (SELECT cpd.checkpoint_id,xmlelement("root", xmlagg(
12 xmltype('<nde seq="' || cpd.sequence_number || '"><![CDATA['||cpd.checkpoint_data||']]></nde>'))) xmlstr
13 FROM Checkpoint_Data cpd, Checkpoint cp, Transaction tr
14 WHERE cpd.checkpoint_id = cp.checkpoint_id
15 and cp.location = 'someLocation'
16 and cp.trans_id = tr.trans_id
17 and tr.time <= sysdate
18 group by cpd.checkpoint_id) c;
XML
--------------------------------------------------------------------------------
<root><a>1st node</a><b>2nd node</b><compType><a>foo</a></compType><d>another no
de</d></root>
だから私は各xmlフラグメントを取り、それを次のようなCDATAノードに変換しました:
<node seq="1"><!CDATA[<root><a>1st node</a><b>2nd node</b>]]></node>
次に、XMLAGG
これらを次のような1つのドキュメントにまとめるために使用されます
<root>
<node seq="1"><!CDATA[<root><a>1st node</a><b>2nd node</b>]]></node>
<node seq="3"><!CDATA[</root>]]></node>
<node seq="2"><!CDATA[<compType><a>foo</a></compType><d>another node</d>]]></node>
</root>
注:シーケンスはgroup by..によってジャンブされる可能性があるため、XSLを適用して順序付けし、印刷しました(必要に応じて、独自の集計を記述してこれを実行するか、pl/sql
すべてのフラグメントを取得するルーチンを記述して、それらを順番に追加してください。それがオプションの場合は、それをお勧めします)。
注:10gでは、Oracleはdisable-output-escapingを無視しているようです(11gでは問題ありません)。10gを使用する場合は、dbms_xmlgen.convert(clob, 1)
それをデコードするための呼び出しを追加できます。
select dbms_xmlgen.convert(
xmlserialize(
content c.xmlstr.transform(xmltype('<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" omit-xml-declaration = "yes" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="/root/node">
<xsl:sort select="@seq"/>
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>')) as clob), 1) xsl, xmlstr
from (SELECT cpd.checkpoint_id,xmlelement("root", xmlagg(
xmltype('<node seq="' || cpd.sequence_number || '"><![CDATA['||cpd.checkpoint_data||']]></node>'))) xmlstr
FROM Checkpoint_Data cpd, Checkpoint cp, Transaction tr
WHERE cpd.checkpoint_id = cp.checkpoint_id
and cp.location = 'someLocation'
and cp.trans_id = tr.trans_id
and tr.time <= sysdate
group by cpd.checkpoint_id) c;
フィドル:http ://sqlfiddle.com/#!4 / e1bf8 / 1