Funkcja wyodrębniania jest przestarzała przez długi czas (przynajmniej od czasu 11gR2 - patrz uwaga w tej dokumentacji).
Jeśli masz wiele wartości i możesz chcieć zobaczyć więcej niż jedną, możesz użyć XMLTable, który usuwa szum CDATA (ale może wymagać przycięcia, ponieważ masz spacje w wartościach):
select x.stu_name, x.birthday,
trim(stu_name) as stu_name2, to_char(x.birthday,'YYYY-MM-DD') as birthday2
from your_table t
cross join xmltable ('/RESPONSE/INFO' passing t.doc
columns
stu_name varchar2(30) path 'STU_NAME',
birthday date path 'BIRTHDAY'
) x
where x.stu_name like '%M%'
STU_NAME BIRTHDAY STU_NAME2 BIRTHDAY2
-------- --------- --------- ---------
Maria 12-MAR-12 Maria 2012-03-12
Jeśli kierujesz na pojedynczą wartość, możesz również użyć xmlquery, która jest bliższa Twojemu wyciągowi:
select regexp_replace(
xmlquery('/RESPONSE/INFO[contains(BIRTHDAY, "2012-03-12")]/STU_NAME/text()'
passing doc
returning content),
'<!\[CDATA\[ *(.*?) *\]\]>', '\1') as stu_name
from your_table t
STU_NAME
--------
Maria
Oto szukałem urodzin, które chciałeś jako tekst w węźle i otrzymałem pasującą nazwę; ale ponieważ nadal ma CDATA, jest mniej więcej taki sam, jak to, co miałeś. Użyłem więc wyrażenia regularnego, aby usunąć część CDATA, chociaż można również użyć substr/instr, jeśli wydajność ma znaczenie.