convert XML to table in oracle - sql

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;

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

Parsing XML with XMLTable n Oracle

I have one xml which holds customer and order details. I am parsing it using XMLTable. I think I am giving the correct XPath but I am getting no output.
Here is what I have tried. Hoping for assistance.
**DECLARE
l_raw_xml CLOB:= '<?xml version="1.0" encoding="utf-8"?>
<Root
xmlns="http://www.adventure-works.com">
<Customers>
<Customer CustomerID="GREAL">
<CompanyName>Great Lakes Food Market</CompanyName>
<ContactName>Howard Snyder</ContactName>
<ContactTitle>Marketing Manager</ContactTitle>
<Phone>(503) 555-7555</Phone>
<FullAddress>
<Address>2732 Baker Blvd.</Address>
<City>Eugene</City>
<Region>OR</Region>
<PostalCode>97403</PostalCode>
<Country>USA</Country>
</FullAddress>
</Customer>
</Customers>
<Orders>
<Order>
<CustomerID>LETSS</CustomerID>
<EmployeeID>6</EmployeeID>
<OrderDate>1997-11-10T00:00:00</OrderDate>
<RequiredDate>1997-12-08T00:00:00</RequiredDate>
<ShipInfo ShippedDate="1997-11-21T00:00:00">
<ShipVia>2</ShipVia>
<Freight>45.97</Freight>
<ShipName>Let Stop N Shop</ShipName>
<ShipAddress>87 Polk St. Suite 5</ShipAddress>
<ShipCity>San Francisco</ShipCity>
<ShipRegion>CA</ShipRegion>
<ShipPostalCode>94117</ShipPostalCode>
<ShipCountry>USA</ShipCountry>
</ShipInfo>
</Order>
</Orders>
</Root>';
l_xml_type XMLTYPE:=XMLTYPE.createXML(l_raw_xml);
cursor c_make_xml_object
is
SELECT x.*,
y.*
FROM XMLTABLE('/Root/Customers/Customer'
PASSING l_xml_type
COLUMNS
CustomerID VARCHAR2(255) PATH '#CustomerID',
CompanyName VARCHAR2(255) PATH 'CompanyName',
FullAddress XMLTYPE PATH 'FullAddress') x,
XMLTABLE('/FullAddress'
PASSING x.FullAddress
COLUMNS
Address VARCHAR2(255) PATH 'Address',
City VARCHAR2(255) PATH 'City') y ;
BEGIN
FOR rec IN c_make_xml_object
loop
DBMS_OUTPUT.PUT_LINE(rec.CustomerID);
DBMS_OUTPUT.PUT_LINE(rec.CompanyName);
END LOOP;
END;
/**
Do I have to account for the namespace? I had added namespace code but it did not work/
Change to this to include a default namespace:
FROM XMLTABLE(xmlnamespaces(default 'http://www.adventure-works.com'),
'/Root/Customers/Customer' ....
....
XMLTABLE(xmlnamespaces(default 'http://www.adventure-works.com'), '/FullAddress'
.....
Yes, a proper namespace definition is needed within the SQL query such as below :
SELECT x.*, y.*
FROM XML_TAB t,
XMLTABLE(XMLnamespaces('http://www.adventure-works.com' as "ns"),
'ns:Root/ns:Customers/ns:Customer'
PASSING t.xml_data
COLUMNS
CustomerID VARCHAR2(255) PATH '#CustomerID',
CompanyName VARCHAR2(255) PATH 'ns:CompanyName',
FullAddress XMLTYPE PATH 'ns:FullAddress'
) x,
XMLTABLE(XMLnamespaces('http://www.adventure-works.com' as "ns"),
'ns:FullAddress'
PASSING x.FullAddress
COLUMNS
Address VARCHAR2(255) PATH 'ns:Address',
City VARCHAR2(255) PATH 'ns:City') y ;
Demo with SQL
Demo with PL/SQL

oracle XML to Database table

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

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 ?