i have the following input XML:
<?xml version="1.0"?>
<Employees>
<Employee emplid="1111">
<lastname>Watson</lastname>
<age>30</age>
<email>johnwatson#sh.com</email>
</Employee>
<Employee emplid="2222">
<firstname>Sherlock</firstname>
<lastname>Holmes</lastname>
<age>32</age>
<email>sherlock#sh.com</email>
</Employee>
</Employees>
Please notice the firstname missing from the employee 1111
I'm executing following select:
select
c1.emplid,
fname,
lname
from(
select emplid, xmldata from employeeXML
LATERAL VIEW explode (xpath(xmldata,'/Employees/Employee/#emplid')) dummyTable as emplid )c1
LATERAL VIEW explode (xpath(xmldata,concat('/Employees/Employee[#id="',c1.emplid,'"',']/firstname/text()')))dummyTable2 as fname
LATERAL VIEW explode (xpath(xmldata,concat('/Employees/Employee[#id="',c1.emplid,'"',']/lastname/text()'))) dummyTable3
as lname;
The expected result :
1111 NULL Watson
2222 Sherlock Holmes
Please notice that NULL value for the missing first name)
however i'm getting the following result:
2222 Sherlock Holmes
Becasue the first name is missing for the employee 1111, i'm not getting the first employee back in my query.
Is there a way to get both employee data back as indicated in the expected result with first name set to NULL and/or space when it is missing ?
Please help.
thanks,
You can always concatenate the result with an empty string, this should probably be fine:
concat(/Employees/Employee[#id="..."]/firstname/text(), '')
This is not the concatenate you used in hive, but an internal XPath function, so you will probably apply both the XPath and Hive concat in one line.
By the way, I guess you want to use #emplid instead of #id to match your data?
Related
Can you please help me out to fix the following?
I only required a person_number once eg. 1000142 but I'm getting 10001421000142 like this.
Because the values I have in XML cell have repeating number, so I only want to extract one unique person number.
select xmltype('<?xml version="1.0"?>
<ROWSET>
<ROW0> <PERSON_NUMBER>1000142</PERSON_NUMBER> <LOAN_1>25000</LOAN_1> <LOAN_2>26000</LOAN_2>
</ROW0>
<ROW0> <PERSON_NUMBER>1000142</PERSON_NUMBER> </ROW0> <LOAN_1>25000</LOAN_1> <LOAN_2>26000</LOAN_2>
</ROW0>
</ROWSET>').extract( '//PERSON_NUMBER/text()' ).getstringval() p#
from dual;
Based on your initial version of the question (where the XML is a valid with a single root element rather than a forest of elements), you can use:
select xmltype(
'<?xml version="1.0"?>
<ROWSET>
<ROW>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<PERSON_NUMBER>1000142</PERSON_NUMBER>
<LOAN_1>25000</LOAN_1>
<LOAN_2>26000</LOAN_2>
</ROW>
</ROWSET>').extract( '//PERSON_NUMBER[1]/text()' ) .getstringval() p#
from dual;
Which outputs:
P#
1000142
db<>fiddle here
I have created a query to pull data from XML column of table however I am having issue when XML has list of data i.e.
Cola Brand has multiple code inside
See My query
select extract(cola_info, '/ns2:cola/coke/bottleCode', 'xmlns:ns2="http://myColaStaticInfo.com"') as op;
Output is something like
I would like to have highlighted content one after another and not together in one column.
Any idea!!!
MY XML look like this
<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>
<ns2:cola xmlns:ns2="http://myColaStaticInfo.com">
<coke>
<code>Bottle_2829</code>
<label>Mirinda</label>
</coke>
<coke>
<code>Bottle_2830</code>
<label>Mirinda</label>
</coke>
<coke>
<code>Bottle_2831</code>
<label>Mirinda</label>
</coke>
</ns2:cola>
XMLTable is probably your best choice for this. Especially since extract has been deprecated.
with example_data as (select xmltype('<?xml version="1.0" encoding="ISO-8859-15" standalone="yes"?>
<ns2:cola xmlns:ns2="http://myColaStaticInfo.com">
<coke>
<code>Bottle_2829</code>
<label>Mirinda</label>
</coke>
<coke>
<code>Bottle_2830</code>
<label>Mirinda</label>
</coke>
<coke>
<code>Bottle_2831</code>
<label>Mirinda</label>
</coke>
</ns2:cola>') as xml from dual)
-- query
select bottle_coke
from example_data e
cross join XMLTABLE(XMLNAMESPACES('http://myColaStaticInfo.com' as "ns2"),
'/ns2:cola/coke'
PASSING e.xml
COLUMNS
bottle_coke XMLTYPE PATH 'code'
) xt;
Output:
<code>Bottle_2829</code>
<code>Bottle_2830</code>
<code>Bottle_2831</code>
I'm trying to get the values of the attributes from table MVR_DTL in column VENDOR_XML. VENDOR_XML is of datatype clob and contains an xml that looks like this
<?xml version="1.0" encoding="UTF-8"?>
<MVRCHPINFF_1.0>
<MVRRecLoop>
<CLoop>
<CRec>
<C_MVRNumberAddr>ROMAN GENERAL</C_MVRNumberAddr>
</CRec>
<CRec>
<C_MVRNumberAddr>ROMAN ST</C_MVRNumberAddr>
</CRec>
<CRec>
<C_MVRNumberAddr>ROMAN CITY, ROME 111111</C_MVRNumberAddr>
</CRec>
</CLoop>
</MVRRecLoop>
</MVRCHPINFF_1.0>
I tried running
SELECT c.Address
from MVR_DTL M, XMLTABLE('/MVRCHPINFF_1.0/MVRRecLoop/CLoop/CRec'
passing XMLTYPE(M.VENDOR_XML)
columns Address XMLTYPE PATH './C_MVRNumberAddr') c;
I'm expecting something like
ROMAN GENERAL ROMAN ST ROMAN CITY, ROME 111111
but i only get 'Statement has failed, however your database does not return any error information.'
Oracle version 12.2.0.1.0
SELECT c.Address from MVR_DTL M,
XMLTABLE(
'string-join(/MVRCHPINFF_1.0/MVRRecLoop/CLoop/CRec/C_MVRNumberAddr, " ")'
passing XMLTYPE(M.VENDOR_XML)
columns Address varchar2(200) PATH '.') c;
How to display parent tags and attributes from XML TYPE column using stored procedure?
Example: I have below data in XMLTYPE Column in one table:
<Employee>
<Employee_information >
<Employee_content>
<task>
<Employee_stem>
<Employee_stem_paragraph>fsdbnfjksdflsdj.</Employee_stem_paragraph>
<Employee_stem_paragraph>dsfsdfsdfsdf</Employee_stem_paragraph>
</Employee_stem>
<Employee_response>
<Employee_response_choices>
<Employee_choice_list>
<Employee_block_choice numeric_identifier="1">
<Employee_choice_paragraph>sdfsdfsdfsdf</Employee_choice_paragraph>
</Employee_block_choice>
</Employee_choice_list>
</Employee_response_choices>
</Employee>
Output: display all the parent tags and attributes in it.
Output example:
Employee,Employee_information,Employee_content,Employee_stem,Employee_stem_paragraph,Employee_response,Employee_response_choices,Employee_choice_list,Employee_block_choice,
numeric_identifier,Employee_choice_paragraph.
In general you have to fix you xml. All tag have to be closed.
1-st select //*/name(.) - extract only element's name.
2-en select '//*/name(#*) -extract only attributes' name.
select *
from xmltable('//*/name(.)'
passing xmltype('<Employee>
<Employee_information>
<Employee_content>
<task>
<Employee_stem>
<Employee_stem_paragraph>fsdbnfjksdflsdj.</Employee_stem_paragraph>
<Employee_stem_paragraph>dsfsdfsdfsdf</Employee_stem_paragraph>
</Employee_stem>
<Employee_response>
<Employee_response_choices>
<Employee_choice_list>
<Employee_block_choice numeric_identifier="1">
<Employee_choice_paragraph>sdfsdfsdfsdf</Employee_choice_paragraph>
</Employee_block_choice>
</Employee_choice_list>
</Employee_response_choices>
</Employee_response>
</task>
</Employee_content>
</Employee_information>
</Employee>') columns name varchar2(200) path '.' )
union all
select *
from xmltable('//*/name(#*)'
passing xmltype('<Employee>
<Employee_information>
<Employee_content>
<task>
<Employee_stem>
<Employee_stem_paragraph>fsdbnfjksdflsdj.</Employee_stem_paragraph>
<Employee_stem_paragraph>dsfsdfsdfsdf</Employee_stem_paragraph>
</Employee_stem>
<Employee_response>
<Employee_response_choices>
<Employee_choice_list>
<Employee_block_choice numeric_identifier="1">
<Employee_choice_paragraph>sdfsdfsdfsdf</Employee_choice_paragraph>
</Employee_block_choice>
</Employee_choice_list>
</Employee_response_choices>
</Employee_response>
</task>
</Employee_content>
</Employee_information>
</Employee>') columns name varchar2(200) path '.' )
i have a table in which i store the information (product id and description ) of all my products, description column is of type VarChar2(200). i want to format the output of this column in select statement to only result me specific part of output string. E.G Here is my simple select statement:
Select PRODUCTId, PRODUCT_DESC From ProductTable Order By PRODUCTId Desc;
this statement result me the output as:
ProductId Product_Desc
1 Oxford English-Oxford-Oxford Press-Textbook
now i want only the specific part of the output result from product_description column. i have already checked Trim() function but that did not helped me. can someone help me?
A substring function may help.
SELECT SUBSTR('ABCDEFG',3,4) "Substring"
FROM DUAL;
You can use SUBSTR() function. You can provide start and end position for the product_desc column.
The query should be like:
Select product_id,substr(product_desc,2,4) from producttable;
Here you'll get 4 chars from the second one.