oracle XML to Database table - sql

I have XML like this . I am unable to parse it into a table
<REQMST>
<ROW>
<REQ_ID>668 </REQ_ID>
<RequestDetails>
<REQ_DTL_ID>845</REQ_DTL_ID>
<INTERFACE_REFNUM>1</INTERFACE_REFNUM>
</RequestDetails>
<RequestDetails>
<REQ_DTL_ID>846</REQ_DTL_ID>
<INTERFACE_REFNUM>2</INTERFACE_REFNUM>
</RequestDetails>
</ROW>
</REQMST>
I am trying to parse it into table using
select *
FROM XMLTABLE('/REQMST/ROW'
PASSING
xmltype('
<REQMST>
<ROW>
<REQ_ID>668 </REQ_ID>
<RequestDetails>
<REQ_DTL_ID>845</REQ_DTL_ID>
<INTERFACE_REFNUM>1</INTERFACE_REFNUM>
</RequestDetails>
<RequestDetails>
<REQ_DTL_ID>846</REQ_DTL_ID>
<INTERFACE_REFNUM>2</INTERFACE_REFNUM>
</RequestDetails>
</ROW>
</REQMST>')
COLUMNS
--describe columns and path to them:
REQ_ID varchar2(20) PATH './REQ_ID',
REQ_DTL_ID varchar2(20) PATH './RequestDetails/REQ_DTL_ID',
INTERFACE_REFNUM varchar2(20) PATH './RequestDetails/INTERFACE_REFNUM'
) xmlt
;
I am getting error ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence
it works if there is only one RequestDetails

You need to go one more level down to get the details from RequestDetails tag using the same technique as parent.
Used column name xml to get the xml as xmltype column and then use xmltable on it to get the further details:
Try this:
select xmlt.req_id, x.REQ_DTL_ID, x.INTERFACE_REFNUM
FROM XMLTABLE('/REQMST/ROW'
PASSING
xmltype('
<REQMST>
<ROW>
<REQ_ID>668 </REQ_ID>
<RequestDetails>
<REQ_DTL_ID>845</REQ_DTL_ID>
<INTERFACE_REFNUM>1</INTERFACE_REFNUM>
</RequestDetails>
<RequestDetails>
<REQ_DTL_ID>846</REQ_DTL_ID>
<INTERFACE_REFNUM>2</INTERFACE_REFNUM>
</RequestDetails>
</ROW>
</REQMST>')
COLUMNS
--describe columns and path to them:
REQ_ID varchar2(20) PATH 'REQ_ID',
xml xmltype PATH 'RequestDetails'
) xmlt, xmltable('/RequestDetails'
passing xmlt.xml
columns
REQ_DTL_ID varchar2(20) PATH 'REQ_DTL_ID',
INTERFACE_REFNUM varchar2(20) PATH 'INTERFACE_REFNUM'
) x;
Produces:
REQ_ID REQ_DTL_ID INTERFACE_REFNUM
668 845 1
668 846 2

Related

How to extract only the subtag in this xml element

with this query I can select the content of tag
select xmltype(
'<?xml version="1.0"?>
<ROWSET>
<ROW>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<LOAN_1>25000</LOAN_1>
</ROW>
<ROW>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<LOAN_1>25000</LOAN_1>
</ROW>
</ROWSET>'
).extract( '/ROWSET/ROW' ) .getstringval() p#
from dual;
<PERSON_NUMBER>1000142</PERSON_NUMBER><LOAN_1>25000</LOAN_1><PERSON_NUMBER>1000142</PERSON_NUMBER><LOAN_1>25000</LOAN_1>
but what I want is to have a list of the sub-tag.
the expected result for this example would be:
PERSON_NUMBER, LOAN_1
code
Similar to an answer to your previous question, you can get the name() XPATH value:
SELECT DISTINCT name
from XMLTABLE(
'/ROWSET/ROW/*'
PASSING xmltype(
'<?xml version="1.0"?>
<ROWSET>
<ROW>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<LOAN_1>25000</LOAN_1>
<LOAN_2>26000</LOAN_2>
</ROW>
<ROW>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<LOAN_1>25000</LOAN_1>
<LOAN_2>26000</LOAN_2>
</ROW>
</ROWSET>'
)
COLUMNS
name VARCHAR2(200) PATH './name()'
);
Outputs:
NAME
PERSON_NUMBER
LOAN_1
LOAN_2
db<>fiddle here

Oracle XMLTABLE and XPATH

I'm a bit lost with Xpath, I'm trying to get attributes from a XML, I'm currently using :
XMLTABLE('/attrs/attr[#name="ImagesWEB"]/string'
PASSING XMLTYPE(XML)
COLUMNS IMAGESWEB VARCHAR2(100) PATH '.'
)
But I need to get an other value with attribute name Image2, so I did an other XMLTABLE but I guess it's not the right way to do it, I have to use XMLTABLE('/attrs/attr'... with two columns, but don't know how can I get both (Image2 can be missing form the XML data) form XPATH ?
Here an XML example (coming for my product's CLOB) :
<attrs>
<attr multiple="true" name="Image2">
<string>IMG2.PNG</string>
<string>IMG3.PNG</string>
<string>IMG4</string>
</attr>
<attr multiple="true" name="ImagesWEB">
<string>IMG.PNG</string>
</attr>
<attr name="ShortLink">
<string>/PRODUCT.html</string>
</attr>
<attr name="TITRE">
<string>TITLE</string>
</attr>
<attr name="name">
<string>PRODUCT</string>
</attr>
</attrs>
Thansk!
You can change your main XPath to just get the attrs, and then filter which you want in the Xpath for each columns clause:
XMLTABLE('/attrs'
PASSING XMLTYPE(XML)
COLUMNS
IMAGESWEB VARCHAR2(100) PATH 'attr[#name="ImagesWEB"]/string',
IMAGE2 VARCHAR2(100) PATH 'attr[#name="Image2"]/string'
)
db<>fiddle with some made-up data.
But what if I have two values (it might happen) ?
If you can have multiple string nodes under an attribute then you can get both attr nodes from one XMLTable call, and then have two more - one for each attr - to get the strings:
SELECT t.id, x2.imagesweb, x3.image2
FROM your_table t
CROSS APPLY
XMLTABLE('/attrs'
PASSING XMLTYPE(t.XML)
COLUMNS
IMAGESWEB XMLTYPE PATH 'attr[#name="ImagesWEB"]',
IMAGE2 XMLTYPE PATH 'attr[#name="Image2"]'
) x1
OUTER APPLY
XMLTABLE('/attr/string'
PASSING x1.imagesweb
COLUMNS
IMAGESWEB VARCHAR2(100) PATH '.'
) x2
OUTER APPLY
XMLTABLE('/attr/string'
PASSING x1.image2
COLUMNS
IMAGE2 VARCHAR2(100) PATH '.'
) x3
ID IMAGESWEB IMAGE2
-- --------- ----------
1 ABC DEF
2 ABC
3 DEF
3 DEF2
4 IMG.PNG IMG2.PNG
4 IMG.PNG IMG3.PNG
4 IMG.PNG IMG4
db<>fiddle with mix of made-up and sample data.
This uses cross apply and outer apply (because one or the other attribute might not exist), which are available from Oracle 12c (12.1.0.1).

convert XML to table in oracle

I have a XML in the below format, store in column of XMLType in oracle database
<a>
<c>1</c>
<c>2</c>
</a>
I need to convert this in table format as
c
1
2
Any idea how to do this using SQL?
with data as
(select '<a><c>1</c><c>2</c></a>' xmlval
from dual)
( select c
from data d,
xmltable('/a/*' passing xmltype(d.xmlval)
columns
c varchar2(254) path '/c'
))
There is answer in this url.
For instance user daggett did this:
select *
FROM XMLTABLE('/person/row'
PASSING
xmltype('
<person>
<row>
<name>Tom</name>
<Address>
<State>California</State>
<City>Los angeles</City>
</Address>
</row>
<row>
<name>Jim</name>
<Address>
<State>California</State>
<City>Los angeles</City>
</Address>
</row>
</person>
')
COLUMNS
--describe columns and path to them:
name varchar2(20) PATH './name',
state varchar2(20) PATH './Address/State',
city varchar2(20) PATH './Address/City'
) xmlt
;
Thanks, it's work.
pISLEMLER CLOB;
select *
FROM XMLTABLE('/mydata/UCRET'
PASSING
xmltype('<mydata>'||pISLEMLER||'</mydata>
')
COLUMNS
--describe columns and path to them:
F_M_IS_ID varchar2(20) PATH './FMISID',
ISKONTO varchar2(20) PATH 'ISK'
) xmlt;

Extract xml data using oracle query

Oracle version 11g
HI ,
When trying to read the XML in a LOOP the query is giving an error but if, I change this to a non existing path then the query is running fine . However the #Name is not fetching is the expected . What should I correct here to make it give the desired output given below:
sqlfiddle link
Non exsisting path described above, removed the E from the name : for $i in AuxiliaryObject/Row return <C>{$i}<R>{AuxiliaryObject/#NAM}
code :
SELECT *
FROM XMLTABLE (
'<C> {for $i in AuxiliaryObject/Row return <C>{$i}<R>{AuxiliaryObject/#NAM}</R></C>}</C>/C'
PASSING xmltype(
'<AuxiliaryType>
<AuxiliaryObject id="1" NAME="Provider_P107">
<Row>
<Index_id>1</Index_id>
<Provider_ID_description>GNRCN</Provider_ID_description>
<Provider_ID>GNRCN</Provider_ID>
</Row>
<Row>
<Index_id>2</Index_id>
<Provider_ID_description>EGUT12</Provider_ID_description>
<Provider_ID>EGUT12 </Provider_ID>
</Row>
</AuxiliaryObject>
<AuxiliaryObject id="2" NAME="Provider_P108">
<Row>
<Index_id>1</Index_id>
<Provider_ID_description>GNRCN</Provider_ID_description>
<Provider_ID>GNRCN</Provider_ID>
</Row>
<Row>
<Index_id>2</Index_id>
<Provider_ID_description>EGUT</Provider_ID_description>
<Provider_ID>EGUT </Provider_ID>
</Row>
</AuxiliaryObject>
</AuxiliaryType>'
).EXTRACT ('AuxiliaryType/*')
COLUMNS
Name varchar (30) Path 'R/#NAME',
Index_Id VARCHAR2 (10) PATH 'Row/Index_id',
Provider_id_description VARCHAR2 (30) PATH 'Row/Provider_ID_description',
provider_id VARCHAR2 (30) PATH 'Row/Provider_ID')
Output : Desired :
ID, Provider_Name, Index, Provider_ID_description, Provider_ID
1 Provider_P107 1 GNRCN GNRCN
1 Provider_P107 2 INDF1 INDF1
2 Provider_P108 2 EGUT12 EGUT12
2 Provider_P108 1 EGUT EGUT
Output coming is in the sqlfiddle link.
The above Queation is a link to this :
Extract data from a XML and load it into a table
When I run the query on Toad : Output is :
NAME INDEX_ID PROVIDER_ID_DESCRIPTION PROVIDER_ID
Provider_P107Provider_P108 1 GNRCN GNRCN
Provider_P107Provider_P108 2 EGUT12 EGUT12
Provider_P107Provider_P108 1 GNRCN GNRCN
Provider_P107Provider_P108 2 EGUT EGUT
I would extract the data in stages:
SELECT xobjects.id, xobjects.name, xrows.index_id,
xrows.provider_id_description, xrows.provider_id
FROM XMLTABLE(
'/AuxiliaryType/AuxiliaryObject'
PASSING xmltype(
'<AuxiliaryType>
<AuxiliaryObject id="1" NAME="Provider_P107">
<Row>
<Index_id>1</Index_id>
<Provider_ID_description>GNRCN</Provider_ID_description>
<Provider_ID>GNRCN</Provider_ID>
</Row>
<Row>
<Index_id>2</Index_id>
<Provider_ID_description>EGUT12</Provider_ID_description>
<Provider_ID>EGUT12 </Provider_ID>
</Row>
</AuxiliaryObject>
<AuxiliaryObject id="2" NAME="Provider_P108">
<Row>
<Index_id>1</Index_id>
<Provider_ID_description>GNRCN</Provider_ID_description>
<Provider_ID>GNRCN</Provider_ID>
</Row>
<Row>
<Index_id>2</Index_id>
<Provider_ID_description>EGUT</Provider_ID_description>
<Provider_ID>EGUT </Provider_ID>
</Row>
</AuxiliaryObject>
</AuxiliaryType>'
)
COLUMNS
name VARCHAR2(30) PATH '#NAME',
id VARCHAR2(10) PATH '#id',
xrows XMLTYPE PATH 'Row') xobjects,
XMLTABLE(
'/Row'
PASSING xobjects.xrows
COLUMNS
index_id VARCHAR2(10) PATH 'Index_id',
provider_id_description VARCHAR2(30) PATH 'Provider_ID_description',
provider_id VARCHAR2(30) PATH 'Provider_ID') xrows;
The XMLTable xobjects contains each of the AuxiliaryObject instances within the AuxiliaryType, from your original XML text. It has the attributes name and id, plus a sub-XMLType containing the nested rows. The second XMLTable, xrows, expands that so the elements can be extracted. The joins and passing of the XML types creates the hierarchy that gives the output you want:
ID NAME INDEX_ID PROVIDER_ID_DESCRIPTION PROVIDER_ID
---------- ------------------------------ ---------- ------------------------------ ------------------------------
1 Provider_P107 1 GNRCN GNRCN
1 Provider_P107 2 EGUT12 EGUT12
2 Provider_P108 1 GNRCN GNRCN
2 Provider_P108 2 EGUT EGUT
This works in SQL Developer against an 11.2.0.3 database, and in SQL Fiddle.
An earlier CTE-based version of this answer also worked in SQL Developer but SQL Fiddle got an ORA-600 error; that along with the issue you had in the question suggests maybe SQL Fiddle is on an unpatched, or at least differently patched, version of 11gR2 which has bugs in the XML handling.

Extract data from a XML and load it into a table

How would I fetch the data from a XML (loaded into a Oracle table) and create a table to load that extracted data.
I'm trying to create a table, with columns as follows, the below mentioned columns are tags in the xml
ID, Provider_Name, Index, Provider_ID_description, Provider_ID
1, Provider_P107, 1, GNRCN, GNRCN
1, Provider_P107, 2, INDF1, INDF1
2, Provider_EGUT, 1, EGUT, EGUT
The XML is:
<?xml version="1.0" encoding="us-ascii"?>
<AuxiliaryType auxiliaryTypeId="1617309" base="Value list" hasImplementation="false" isShared="true" masteredIn="false" name="ID list" type="String">
<AuxiliaryObject id="1" name="Provider_P107">
<Row>
<Index>1</Index>
<Provider_ID_description>GNRCN</Provider_ID_description>
<Provider_ID>GNRCN</Provider_ID>
</Row>
<Row>
<Index>2</Index>
<Provider_ID_description>INDF1</Provider_ID_description>
<Provider_ID>INDF1</Provider_ID>
</Row>
</AuxiliaryObject>
<AuxiliaryObject id="2" name="Provider_EGUT">
<Row>
<Index>1</Index>
<Provider_ID_description>EGUT</Provider_ID_description>
<Provider_ID>EGUT</Provider_ID>
</Row>
</AuxiliaryObject>
</AuxiliaryType>
I've tried using the following query:
SELECT w.ID,
p.Name,
s.Index,
q.P_Desc,
q.P_ID
from traptabclob t
left join xmltable ('/AuxiliaryType/AuxiliaryObject/'
passing t.testclob
columns ID XmlType path '/AuxiliaryType/AuxiliaryObject/#id',
columns Name XmlType path '/AuxiliaryType/AuxiliaryObject/#name',
columns Index XmlType path 'Row/Index',
columns P_Desc varchar2(201) path 'Row/Provider_ID_description',
columns P_ID varchar2(21) path 'Row/Provider_ID',
) q
on (1=1)
left join xmltable('/Index'
passing q.Index
columns Index number path '.') s
on (1=1)
left join xmltable('/AuxiliaryType/AuxiliaryObject/'
passing q.ID
columns ID number path '.') w
on (1=1)
left join xmltable('/AuxiliaryType/AuxiliaryObject/'
passing q.Name
columns Name varchar2(21) path '.') p
on (1=1);
I tried this http://www.sqlfiddle.com/#!4/1a672/7/0. Here is the new where I am able to fetch more data http://www.sqlfiddle.com/#!4/1a672/8/0, but I'm still struggling. This does not work when I have more than one index or row. How to do it If I have the count of AuxiliaryObject id ?