Estrarre dati da un XML Type
E' spesso utile accedere ai dati contenuti in una vriabile XML TYpe, usando l' SQL come se fossero in una tabella o vista.
XML ha per sua stessa natura una struttura gerarchica. Di conseguenza viene facile pensare ad un file XML come a record di tabelle legate tra loro da relazioni master-detail.
Pensiamo ad un documento XML memorizzato nella colonna XML Type di una tabella Oracle:
<root>
<master id ='A'>
<info>First Header</info>
<detail>
<info>Detail 1</info>
</detail>
<detail>
<info>Detail 2</info>
</detail>
</master>
<master id = 'B'>
<info>Second Header</info>
<detail>
<info>Detail 3</info>
</detail>
</master>
</root>
Creeremo due viste ("dumb_master" e "dumb_detail") connesse da relazione master-detail relationship e popolate dai dati contenuti nell' XML Document della colonna dumb.dumber.
View "dumb_master"
CREATE OR REPLACE VIEW dumb_master AS
SELECT extractvalue(mstr, '/master/@id') master_id,
extractvalue(mstr, '/master/info') master_info,
mstr master_xml
FROM (SELECT VALUE(mstr) mstr
FROM dumb,
TABLE(xmlsequence(extract(dumber,
'//master'))) mstr);
XMLSequence restituisce una sequenza di XMLType. Usando questa funzione in una "TABLE clause" possiamo mettere in serie i valori in righe multiple e processarle poi in una SELECT. Questa vista restituirà 2 record, una per ogni tag master in XML Document. View "dumb_master" restituirà tante righe quanti sono i tag 'master' all'interno del documento XML, 2 nel nostro caso. La colonna "master_xml" è di tipo "XML Type", contiene il tag master per il record corrente, e verrà usata dalla vista "dumb_detail". Per il record con "master_id" = A, "master_xml" conterrà:
<master id="A">
<info>First Header</info>
<detail>
<info>Detail 1</info>
</detail>
<detail>
<info>Detail 2</info>
</detail>
</master>
View "dumb_detail"
CREATE OR REPLACE VIEW dumb_datail AS
SELECT master_id,
extractvalue(dtl, '/detail/info') detail_info
FROM (SELECT VALUE(dtl) dtl,
master_id
FROM dumb_master,
TABLE(xmlsequence(extract(master_xml,
'//detail'))) dtl);
"dumb_detail" è molto simile a "dumb_master". Una "select * restituirà:
| A | Detail 1 |
| A | Detail 2 |
| B | Detail 3 |
Questo è tutto. Queste tecniche possono essere usate per XML piccoli. Suggerisco le materialize views, per ridurre i tempi legati al esplosione dei file XML.