Comments on: Extracting Master-Detail data from an XMLType with a single SQL statement https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/ Friends of Oracle and Java Thu, 23 Apr 2015 12:54:46 +0000 hourly 1 http://wordpress.org/?v=4.2 By: Marco Gralike https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3985 Sat, 06 Mar 2010 18:33:55 +0000 http://technology.amis.nl/blog/?p=1389#comment-3985 Have a look at the following XMLTABLE with FOR ORIDINALITY example, where in this case the “GrossDividentRate” represents a repeating group of elements in the XML document and is passed as an XML fragment into the next XMLTABLE function:

select xt2.gross_div_rate_cur_code   as "CURRENCY_CODE"
,      xt2.gross_div_rate_cur_amount as "CURRENCY_AMOUNT"
,      xt2.position                  as "ELEMENT_POSITION"
from   my_xmltable_store  cmt
,      xmltable(xmlnamespaces(default 'http://www.website.nl/ns/1.0'),
                '/ApplicationMessage'
                passing cmt.object_value
                  GrossDividendRate         XMLTYPE      path 'CorporateActionDetails'
                ) xt1
,      xmltable(xmlnamespaces(default 'http://www.website.nl/ns/1.0'),
                '/CorporateActionDetails/GrossDividendRate/*'
                passing xt1.GrossDividendRate
                columns
                  POSITION FOR ORDINALITY,
                  gross_div_rate_cur_code    number(5)   path 'CurrencyCode',
                  gross_div_rate_cur_amount  varchar2(8) path 'Amount'
                ) xt2
;

See for more info and howto’s the Oracle OTN XMLDB forum and or my dedicated XMLDB blog, besides my posts on XML DB on the technology.amis.nl blog.

HTH

Marco

 

]]>
By: Marco Gralike https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3984 Sat, 06 Mar 2010 18:24:14 +0000 http://technology.amis.nl/blog/?p=1389#comment-3984 Some good advice to all who read this post.

Be aware that the propriety XSQL functions are getting deprecated from 11gR2 and onwards.

The table(xmlsequence(extract())) syntax (XPath V1) should only be used in Oracle 1ogR1 and below.

The optimized XMLTABLE function (XPath V2 and XQuery 1.0 compatible) should be used from Oracle 10gR2 and onwards. This functionality is (performance wise) optimized in 10gR2 and onwards while the older propriety functionality is maintained only.  XMLTABLE makes use of the XQuery engine introduced in Oracle 1ogR2.

To answer KILE’s question. Have a look at the FOR ORDINALITY syntax in XMLTABLE to sort out repeating groups/elements. In  principal you can pass on the repeating group to a SECOND XMLTABLE function as a XML Fragment by choosing XMLTYPE as its datatype. In the second XMLTABLE function you refer in the PASSING clause to defined XMLTYPE column in the XMLTABLE function.

You could do the same (passing on XML fragments) with the table(xmlsequence(extract())) construct via the “position” XPath function as an alternative for the FOR ORDINALITY, but I wouldn’t advice this to be used in Oracle 10gR2. To make this more interesting. Officially, despite that it works, the “position” xpath function is not supported by Oracle in 10g and below…

…AND ALWAYS, ALWAYS try to use the full XPATH.

Avoid, but better, NEVER USE WILDCARD’s like “*” or “//”, if you favor performance. By giving the XML parser (or in some cases the Oracle Cost based Optimizer) only such hints to work with, the whole XML document will be searched. In effect this is very very very inefficient regarding memory and CPU use… You have been warned by someone who nowadays knows…

HTH

Marco
 

]]>
By: KILE https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3983 Sat, 06 Mar 2010 13:22:47 +0000 http://technology.amis.nl/blog/?p=1389#comment-3983 Hi,
I’m using the following select to get the values of the items1 field:
SELECT EXTRACT (VALUE (xmltable0), ‘//value/text()’).getstringval () AS nombre_completo
FROM TABLE i, TABLE (XMLSEQUENCE (EXTRACT (i.xml_informe, ‘//main/items2/value’))) xmltable0
Where a record from this table is:
<main>
<items1>
<value>3</value>
<value>5</value>
<value>6</value>
<value>7</value>
<value>8</value>
</items1>
<items2>
<value>3</value>
<value>5</value>
<value>
<value>1-7</value>
<value>1-8</value>
</value>
<value>7</value>
<value>8</value>
</items2>
<main>
So I get 5 rows with values: 3 5 6 7 8.
My question is that sometimes I get more than 1 level of hierarchy, like in items2. How could be a good way to get it? I’m a little lost about how to make it, so any help will be more than welcome.
 
Thank u very much in advance
 
 

]]>
By: Madhu https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3982 Fri, 29 Jan 2010 02:50:07 +0000 http://technology.amis.nl/blog/?p=1389#comment-3982 Hey,

really a very useful article on XML DB. Easy to understand.

]]>
By: Arthur Johnson https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3981 Mon, 22 Oct 2007 19:06:42 +0000 http://technology.amis.nl/blog/?p=1389#comment-3981 Resolved my question with SQL:
SELECT extractvalue(Value(a1), ‘*/ProductReference’) productreference,
extractvalue(Value(a1), ‘*/SerialNumber’) serialnumber,
extractvalue(Value(a1), ‘*/Model’) “model”,
extractvalue(Value(a1), ‘*/Coverage’) coverage,
extractvalue(Value(a1), ‘*/CoverageStatus’) coveragestatus,
extractvalue(Value(s1), ‘*/CountryCode’) countrycode,
extractvalue(Value(s1), ‘*/CountryName’) countryname,
extractvalue(Value(s1), ‘*/CustomerName’) customername,
extractvalue(Value(s1), ‘*/CustomerNumber’) customernumber,
extractvalue(Value(s1), ‘*/SiteNumber’) sitenumber,
extractvalue(Value(s1), ‘*/SiteShortName’) siteshortname,
extractvalue(Value(s1), ‘*/Address1′) address1,
extractvalue(Value(s1), ‘*/Address2′) address2,
extractvalue(Value(s1), ‘*/City’) city,
extractvalue(Value(s1), ‘*/State’) state,
extractvalue(Value(s1), ‘*/PostalCode’) postalcode,
extractvalue(Value(s1), ‘*/Location’) sitelocation,
extractvalue(Value(s1), ‘*/SitePhoneNumber’) sitephonenumber,
extractvalue(Value(s1), ‘*/ContactName’) contactname,
extractvalue(Value(s1), ‘*/Contactphone’) contactphone,
extractvalue(Value(s1), ‘*/CSRCode’) csrcode,
extractvalue(Value(s1), ‘*/CSRName’) csrname,
extractvalue(Value(s1), ‘*/BranchCode’) branchcode,
extractvalue(Value(s1), ‘*/TerritoryCode’) territorycode,
sdi.sdiid as reqid
FROM aradmin.sdi_xml_tab sdi,
TABLE (xmlsequence (extract (sdidocxml, ‘*/Assets/Asset’))) a1,
TABLE (xmlsequence (extract (value(a1), ‘*/Site’))) s1

Thanks,
Arthur

]]>
By: Arthur Johnson https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3980 Mon, 22 Oct 2007 16:56:14 +0000 http://technology.amis.nl/blog/?p=1389#comment-3980 I have a similar structured XML where I would like to display each Asset’s tags and the Site tags for each Asset. when I run the query below, I get error- ORA-00904: “ASSET”: invalid identifier. What’s wrong?

XML:
===

+






















.
.
.

200
84

QUERY:
=====
SELECT extractvalue(Value(a1), ‘*/ProductReference’) productreference,
extractvalue(Value(a1), ‘*/SerialNumber’) serialnumber,
extractvalue(Value(a1), ‘*/Model’) “model”,
extractvalue(Value(a1), ‘*/Coverage’) coverage,
extractvalue(Value(a1), ‘*/CoverageStatus’) coveragestatus,
extractvalue(Value(s1), ‘*/CountryCode’) countrycode,
extractvalue(Value(s1), ‘*/CountryName’) countryname,
extractvalue(Value(s1), ‘*/CustomerName’) customername,
extractvalue(Value(s1), ‘*/CustomerNumber’) customernumber,
extractvalue(Value(s1), ‘*/SiteNumber’) sitenumber,
extractvalue(Value(s1), ‘*/SiteShortName’) siteshortname,
extractvalue(Value(s1), ‘*/Address1′) address1,
extractvalue(Value(s1), ‘*/Address2′) address2,
extractvalue(Value(s1), ‘*/City’) city,
extractvalue(Value(s1), ‘*/State’) state,
extractvalue(Value(s1), ‘*/PostalCode’) postalcode,
extractvalue(Value(s1), ‘*/Location’) sitelocation,
extractvalue(Value(s1), ‘*/SitePhoneNumber’) sitephonenumber,
extractvalue(Value(s1), ‘*/ContactName’) contactname,
extractvalue(Value(s1), ‘*/Contactphone’) contactphone,
extractvalue(Value(s1), ‘*/CSRCode’) csrcode,
extractvalue(Value(s1), ‘*/CSRName’) csrname,
extractvalue(Value(s1), ‘*/BranchCode’) branchcode,
extractvalue(Value(s1), ‘*/TerritoryCode’) territorycode,
sdi.sdiid as reqid
FROM aradmin.sdi_xml_tab sdi,
TABLE (xmlsequence (extract (Asset, ‘*/Assets’))) a1,
TABLE (xmlsequence (extract (value(a1), ‘*/Asset/Site’))) s1

]]>
By: Alex Nuijten https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3979 Thu, 30 Aug 2007 13:01:54 +0000 http://technology.amis.nl/blog/?p=1389#comment-3979 Thank you, Val for your comments. You can use xpath expressions to refer to attributes.
I’ll put up an example in the body of the post (formatting issue in the comments section)

]]>
By: Val https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3978 Thu, 30 Aug 2007 05:54:04 +0000 http://technology.amis.nl/blog/?p=1389#comment-3978 Thank you for writing this. I do have a question – what if my XML file has only three tags and all the values are in attributes? What’s the syntax of selecting attribute values?

]]>
By: Alex Nuijten https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3977 Thu, 12 Apr 2007 09:17:29 +0000 http://technology.amis.nl/blog/?p=1389#comment-3977 Thank you for your comments Steve. I put an answer to your question in the posting (it is not possible to properly format code in this section). Now that I reread your question I think I interpreted your question wrong. Maybe you don’t want an outerjoin after all. If you don’t want to see the kids without wishlist, but only the kids who do have a wishlist, the queries as the were posted originally do that.

]]>
By: Steve https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3976 Tue, 10 Apr 2007 18:41:45 +0000 http://technology.amis.nl/blog/?p=1389#comment-3976 I’ve been looking at a similar query, but always wondered how to do an inner join if the kids had no wishlist (hard to believe!), i.e. I don’t want to see aa row at all if there is no wishlist for the child.

]]>
By: Alex Nuijten https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3975 Mon, 22 Jan 2007 12:54:51 +0000 http://technology.amis.nl/blog/?p=1389#comment-3975 Thank you, Jaromir. Good point. This is something I probably should have explained more or better (if at all) in this blog.

]]>
By: Jaromir D.B. Nemec https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3974 Fri, 19 Jan 2007 19:30:34 +0000 http://technology.amis.nl/blog/?p=1389#comment-3974 Hi,

> How you got the cartesian product is hard to determine..

not for my as I made the same error:)

the wrong way is to do:

5 FROM t
6 , TABLE (xmlsequence (extract (wishlist, ‘*/child’))) kids
7 , TABLE (xmlsequence (extract (wishlist, ‘*/wishlist/article’))) wl
8 WHERE id = 2

Note the usage of whishlist instead of value (kids) in the second TABLE() line

regards,

Jaromir D.B. Nemec

]]>
By: Alex Nuijten https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3973 Mon, 08 Jan 2007 11:40:40 +0000 http://technology.amis.nl/blog/?p=1389#comment-3973 Hi Alan,

Thank you for your comment.

Table T is the table that looks like this:
create table t
(id number
,wishlist xmltype
)
In this table there are two records, the first one (with ID 1) has a single child’s wishlist. The second one (with ID 2) contains the wishlist of
two children.
The demo-script, included with the blog, contains both the table definition and the contents of this table.

How you got the cartesian product is hard to determine as you didn’t include the query that you used.

When I create another entry in the T-table (with ID 3) like:
INSERT INTO T
VALUES (3, xmltype (‘
Tim
21491269
Crane
12.50
21499517
Keyboard
10
21521591
Crime Investigation Game
9.95
Lara
21539350
Chalk Board
12
21517846
Washing Machine
10
21271168
Winnie the Pooh Bingo
10
Rachel
21539341
Barbie Doll
11.50
‘));
commit;
And issue this query:
SELECT Row_Number() over (PARTITION BY childname
ORDER BY null) rn
, childname
, article_number
, description
, price
from (
select extractvalue (value (kids), ‘*/name’) childname
, extractvalue (value (wl), ‘*/artno’) Article_number
, extractvalue (value (wl), ‘*/description’) description
, extractvalue (value (wl), ‘*/price’) price
FROM t
, TABLE (xmlsequence (extract (wishlist, ‘*/child’))) kids
, TABLE (xmlsequence (extract (value (kids), ‘*/wishlist/article’))) wl
WHERE id = 3
);
This is the result:
1 1 Lara 21539350 Chalk Board 12
2 2 Lara 21517846 Washing Machine 10
3 3 Lara 21271168 Winnie the Pooh Bingo 10
4 1 Rachel 21539341 Barbie Doll 11.50
5 1 Tim 21491269 Crane 12.50
6 2 Tim 21499517 Keyboard 10
7 3 Tim 21521591 Crime Investigation Game 9.95
Hope this answers your questions. And for those of you curious about how got what? Tim got the keyboard and Lara the chalkboard. 😉

]]>
By: Alan Smith https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3972 Fri, 29 Dec 2006 18:24:13 +0000 http://technology.amis.nl/blog/?p=1389#comment-3972 I tried your suggested solutions but had a few problems.

I presume the table with an XMLtype column was called t.

Where is the column id defined?

With multiple names and multiple Article_number, description and price my result set produced

CHILDNAME ARTICLE_NUMBER DESCRIPTION PRICE
Tim 21491269 Crane 12.5
Tim 21499517 Keyboard 10
Tim 21521591 Crime Investigation Game 9.95
Tim 21491255 doll 52.5
Tim 21499517 Keyboard 10
Tim 21521599 Kitchen 29.95
Rachel 21491269 Crane 12.5
Rachel 21499517 Keyboard 10
Rachel 21521591 Crime Investigation Game 9.95
Rachel 21491255 doll 52.5
Rachel 21499517 Keyboard 10
Rachel 21521599 Kitchen 29.95

i.e. a cartesian join between children and Article_number.

Any suggestions?

]]>
By: Paweł Barut https://technology.amis.nl/2006/10/31/extracting-master-detail-data-from-an-xmltype-with-a-single-sql-statement/#comment-3971 Mon, 20 Nov 2006 00:36:31 +0000 http://technology.amis.nl/blog/?p=1389#comment-3971 Very interesting and useful article. Good job!

]]>