Если я понимаю, что вы пытаетесь сделать, вы начинаете со строковой версии XML-документа, например:
<logs><log><ID>123456</ID></log><log><ID>1234567</ID></log></logs>
и пытается добавить значение name
, соответствующее каждому из этих значений id
, которые вы получаете из представления.
Вы можете извлечь все идентификаторы, используя XMLTable, присоединить их к представлению и восстановить окончательный XML с помощью XMLAgg, что-то вроде:
select xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v.id, v.name)))).getclobval()
into out_xml
from xmltable(
'/logs/log'
passing xmltype(in_xml)
columns id number path 'ID'
) x
join your_view v on v.id = x.id;
Как демонстрация в простом SQL, начиная с вашей строки и с CTE для представления вашего представления:
-- CTE to represent your view
with your_view (id, name) as (
select 123456, 'TEST' from dual
union all
select 1234567, 'TEST1' from dual
)
-- actual query
select xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v.id, v.name)))).getclobval()
from xmltable(
'/logs/log'
passing xmltype('<logs><log><ID>123456</ID></log><log><ID>1234567</ID></log></logs>')
columns id number path 'ID'
) x
join your_view v on v.id = x.id;
XMLELEMENT("LOGS",XMLAGG(XMLELEMENT("LOG",XMLFOREST(V.ID,V.NAME)))).GETCLOBVAL()
-----------------------------------------------------------------------------------------------------
<logs><log><ID>123456</ID><NAME>TEST</NAME></log><log><ID>1234567</ID><NAME>TEST1</NAME></log></logs>
или сериализовано для его подтверждения:
-- CTE to represent your view
with your_view (id, name) as (
select 123456, 'TEST' from dual
union all
select 1234567, 'TEST1' from dual
)
-- actual query
select xmlserialize(document
xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v.id, v.name))))
indent) as out_xml
from xmltable(
'/logs/log'
passing xmltype('<logs><log><ID>123456</ID></log><log><ID>1234567</ID></log></logs>')
columns id number path 'ID'
) x
join your_view v on v.id = x.id;
OUT_XML
--------------------------------------------------------------------------------
<logs>
<log>
<ID>123456</ID>
<NAME>TEST</NAME>
</log>
<log>
<ID>1234567</ID>
<NAME>TEST1</NAME>
</log>
</logs>
Если вы действительно хотите использовать механизм, показанный в вопросе, с которым вы связались, то вы можете создать окончательный выходной CLOB, добавив каждый элемент, сгенерированный внутри цикла, с добавлением тега start и end logs
вне цикла:
declare
in_xml clob := '<logs><log><ID>123456</ID></log><log><ID>1234567</ID></log></logs>';
out_xml clob;
v_output clob;
begin
v_output := '<logs>';
for r in (
select id
from xmltable(
'/logs/log'
passing xmltype(in_xml)
columns id number path 'ID'
)
)
loop
select xmlelement("log", xmlforest (id, name)).getclobval()
into out_xml
from your_view where id = r.id;
v_output := v_output || out_xml;
end loop;
v_output := v_output || '</logs>';
dbms_output.put_line (v_output);
end;
/
<logs><log><ID>123456</ID><NAME>TEST</NAME></log><log><ID>1234567</ID><NAME>TEST1</NAME></log></logs>
PL/SQL procedure successfully completed.
Но проще избежать цикла курсора и просто присоединиться один раз:
declare
in_xml clob := '<logs><log><ID>123456</ID></log><log><ID>1234567</ID></log></logs>';
v_output clob;
begin
select xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v.id, v.name)))).getclobval()
into v_output
from xmltable(
'/logs/log'
passing xmltype(in_xml)
columns id number path 'ID'
) x
join your_view v on v.id = x.id;
dbms_output.put_line (v_output);
end;
/
<logs><log><ID>123456</ID><NAME>TEST</NAME></log><log><ID>1234567</ID><NAME>TEST1</NAME></log></logs>
PL/SQL procedure successfully completed.