I have a normal SQL table, one of the column is an XML, example:
...
<Element><id>first</id></Element>
<Element><id>second</id></Element>
...
I need to get the list of id's separated by commas:
id_list
---
first,second
For now, I have achieved it creating an XMLTABLE with the ids:
id
----
first
second
and then using the LISTAGG function of Oracle. I wonder if exist some function/loop (maybe FLWOR?) to get the same result but not converting the XML input to an XMLTABLE.
Thanks a lot for helping
If you must, you could do something like what I show in the query below.
However, I don't view this as a good approach; what you are doing currently, by creating an XML table and then using LISTAGG
, seems better.
with inputs ( xml_str ) as (
select '...
<Element><id>first</id></Element>
<Element><id>second</id></Element>
...'
from dual
)
-- End of test data (not part of the solution); SQL query begins below this line
select rtrim( regexp_replace( xml_str, '.*?(<Element><id>(.*?)</id></Element>|$)'
, '\2,', 1, 0, 'n')
, ',') as id_list
from inputs
;
ID_LIST
------------
first,second
You could so it just within the XMLDB function, with XPath string-join
function .
As an XMLQuery if you have a single value to process (with your sample data provided via a CTE and a dummy root node):
with t (xml) as (
select xmltype('<root>
<Element><id>first</id></Element>
<Element><id>second</id></Element>
</root>') from dual
)
select xmlquery('
for $i in /root
return <e>{ fn:string-join($i/Element/id, ",") }</e>/text()'
passing xml
returning content
) as result
from t;
RESULT
--------------------------------------------------------------------------------
first,second
Or with an XMLTable:
with t (xml) as (
select xmltype('<root>
<Element><id>first</id></Element>
<Element><id>second</id></Element>
</root>') from dual
)
select x.*
from t
cross join xmltable('
for $i in /root
return <e>{ fn:string-join($i/Element/id, ",") }</e>'
passing xml
columns result varchar2(4000) path '.'
) x;
RESULT
--------------------------------------------------------------------------------
first,second
I'm not sure there's much advantage in doing that over listagg()
, but might be interesting to compare the performance of both with your real data, particularly if there are a lot of nodes. Except, by changing the XMLTable column type to CLOB, you can get a larger value out of that version that you can with listagg()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.