XMLSequence to XMLTable
Hi!
I need a help to use XMLTable instead of XMLSequence.
This is the part of my XML.
<emiDocAnt>
<owner>11111111111111</owner>
<idDocAnt>
<idDocAntPap>
<tpDoc>01</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>02</tpDoc>
</idDocAntPap>
</idDocAnt>
<idDocAnt>
<idDocAntPap>
<tpDoc>03</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>04</tpDoc>
</idDocAntPap>
</idDocAnt>
</emiDocAnt>
<emiDocAnt>
<owner>22222222222222</owner>
<idDocAnt>
<idDocAntPap>
<tpDoc>05</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>06</tpDoc>
</idDocAntPap>
</idDocAnt>
</emiDocAnt>I have this statement that works fine, it retruns the data inside the idDocAntPap group and its owner.
SELECT EXTRACTVALUE(VALUE(vw),'/emiDocAnt/owner'),
EXTRACTVALUE(VALUE(vw3), '/idDocAntPap/tpDoc')
FROM tb_projCargaTMP,
TABLE(XMLSequence(EXTRACT(XMLAutorizacao,'/emiDocAnt'))) vw,
TABLE(XMLSequence(EXTRACT(vw.column_value,'//idDocAnt'))) vw2,
TABLE(XMLSequence(EXTRACT(vw2.column_value,'//idDocAntPap'))) vw3;But I'd like to use XMLTable instead of XMLSequence. The problem is: how can I get the "owner" value?
SELECT vw."owner",
vw."tpDoc"
FROM tb_projCargaTMP,
XMLTABLE('/emiDocAnt/idDocAnt/idDocAntPap'
PASSING tb_CargaTMP.XMLAutorizacao
COLUMNS "owner" NUMBER(14) PATH ???, <-- How can I get the owner value?
"tpDoc" NUMBER(2) PATH '/idDocAntPap/tpDoc',
"serie" VARCHAR2(3) PATH '/idDocAntPap/serie',
"subserie" VARCHAR2(2) PATH '/idDocAntPap/subser',
"nDoc" NUMBER(20) PATH '/idDocAntPap/nDoc',
"dEmi" DATE PATH '/idDocAntPap/dEmi'
) vw;Thanks!!!
Based off a similar question in {message:id=4093475}, you have two options, depending upon whether you want to use XQuery or not within XMLTable.
WITH tb_projCargaTMP AS
(SELECT XMLTYPE('<root><emiDocAnt>
<owner>11111111111111</owner>
<idDocAnt>
<idDocAntPap>
<tpDoc>01</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>02</tpDoc>
</idDocAntPap>
</idDocAnt>
<idDocAnt>
<idDocAntPap>
<tpDoc>03</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>04</tpDoc>
</idDocAntPap>
</idDocAnt>
</emiDocAnt>
<emiDocAnt>
<owner>22222222222222</owner>
<idDocAnt>
<idDocAntPap>
<tpDoc>05</tpDoc>
</idDocAntPap>
<idDocAntPap>
<tpDoc>06</tpDoc>
</idDocAntPap>
</idDocAnt>
</emiDocAnt></root>') XMLAutorizacao -- added root node to make valid XML
FROM dual)
SELECT vw.owner, vw2.*
FROM tb_projCargaTMP,
XMLTable('/root/emiDocAnt'
PASSING tb_projCargaTMP.XMLAutorizacao
COLUMNS
owner NUMBER(14) PATH 'owner',
antPapXML XMLTYPE PATH 'idDocAnt/idDocAntPap') vw,
XMLTABLE('/idDocAntPap'
PASSING vw.antPapXML
COLUMNS
tpDoc NUMBER(2) PATH 'tpDoc',
serie VARCHAR2(3) PATH 'serie',
subserie VARCHAR2(2) PATH 'subser',
nDoc NUMBER(20) PATH 'nDoc',
dEmi DATE PATH 'dEmi'
) vw2; and
SELECT vw.*
FROM tb_projCargaTMP,
XMLTable('for $i in /root/emiDocAnt/idDocAnt/idDocAntPap
return element r{$i/../../owner,
$i/tpDoc,
$i/serie}' -- continue on
PASSING tb_projCargaTMP.XMLAutorizacao
COLUMNS
owner NUMBER(14) PATH 'owner',
tpDoc NUMBER(2) PATH 'tpDoc',
serie VARCHAR2(3) PATH 'serie',
subserie VARCHAR2(2) PATH 'subser',
nDoc NUMBER(20) PATH 'nDoc',
dEmi DATE PATH 'dEmi') vw;
Similar Messages
-
Converting XMLSEQUENCE to XMLTABLE
So we've gotten part-way into converting all of our code using XMLSEQUENCE to instead use XMLTABLE and everything compiles fine. However, we now realize (a bit late, I realize, and it is documented) that the PASSING clause with XMLTABLE requires a SQL expression.
All of the XML queries that we use involve the evaluation of a PL/SQL variable - for example, an XMLTYPE variable passed into a procedure. The first example below is using a SQL expression (the return from the XMLTYPE function) in the PASSING clause and this works, but the second example tries to refer to a PL/SQL variable which generates an exception.
Is XMLTABLE totally off the table if you are working with PL/SQL variables, same as if you attempt to refer to a package variable within a SQL statement?
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, Data Mining and Real Application Testing options
sql>begin
2 for rec_pkg in (select *
3 from xmltable('/data/packages/package'
4 passing xmltype(
5 '<data>
6 <packages>
7 <package upc="00054645172462">
8 </package>
9 <package upc="00054645413060">
10 </package>
11 </packages>
12 </data>')
13 columns package_upc varchar2(14) path '@upc')
14 ) loop
15 dbms_output.put_line( 'Package UPC: ' || rec_pkg.package_upc);
16 end loop;
17 end;
18 /
Package UPC: 00054645172462
Package UPC: 00054645413060
PL/SQL procedure successfully completed.
sql>declare
2 v_xml xmltype := xmltype(
3 '<data>
4 <packages>
5 <package upc="00054645172462">
6 </package>
7 <package upc="00054645413060">
8 </package>
9 </packages>
10 </data>');
11 begin
12 for rec_pkg in (select *
13 from xmltable('/data/packages/package'
14 passing v_xml
15 columns package_upc varchar2(14) path '@upc')
16 ) loop
17 dbms_output.put_line( 'Package UPC: ' || rec_pkg.package_upc);
18 end loop;
19 end;
20 /
declare
ERROR at line 1:
ORA-19112: error raised during evaluation:
ORA-06550: line 1, column 13:
PLS-00201: identifier 'SYS.DBMS_XQUERYINT' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at line 12Works fine for me:
declare
v_xml xmltype := xmltype(
'<data>
<packages>
<package upc="00054645172462">
</package>
<package upc="00054645413060">
</package>
</packages>
</data>');
begin
for c in (select * from v$version) loop
dbms_output.put_line(c.banner);
end loop;
for rec_pkg in (select *
from xmltable('/data/packages/package'
passing v_xml
columns package_upc varchar2(14) path '@upc')
) loop
dbms_output.put_line( 'Package UPC: ' || rec_pkg.package_upc);
end loop;
end;
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Prod
PL/SQL Release 10.2.0.3.0 - Production
CORE 10.2.0.3.0 Production
TNS for Linux: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production
Package UPC: 00054645172462
Package UPC: 00054645413060
Statement processed. -
Question on XMLTABLE related to XMLSEQUENCE
Hi Mark,
Easy one for you.
recently i tried XMLTABLE which i used as a replacement for TABLE(XMLSEQUENCE) which was used with versions lower than 10g R2.
here is the test.
SQL> create table xml(data clob)
2 /
Table created.
SQL>
SQL> insert into xml values (
2 '<DeptList>
3 <Dept id="1">
4 <name>XXX</name>
5 <EMP id="111">
6 <name>XXX111</name>
7 </EMP>
8 <EMP id="112">
9 <name>XXX112</name>
10 </EMP>
11 </Dept>
12 <Dept id="2">
13 <name>YYY</name>
14 <EMP id="222">
15 <name>yyy222</name>
16 </EMP>
17 <EMP id="333">
18 <name>yyy112</name>
19 </EMP>
20 </Dept>
21 </DeptList>')
22 /
1 row created.
SQL>
SQL> set linesize 150
SQL> column deptid format 9999
SQL> column dname format a20
SQL> column empid format 9999
SQL> column ename format a20
SQL>
SQL> select
2 cast(extractvalue(value(a), '/Dept/@id') as number ) deptid
3 ,cast(extractvalue(value(a), '/Dept/name') as varchar2(20)) dname
4 ,cast(extractvalue(value(b), '/EMP/@id') as number) empid
5 ,cast(extractvalue(value(b), '/EMP/name') as varchar2(20)) ename
6 from xml
7 ,table(xmlsequence(extract(xmltype(data), '/DeptList/Dept'))) a
8 ,table(xmlsequence(extract(value(a), '/Dept/EMP'))) b
9 /
DEPTID DNAME EMPID ENAME
1 XXX 111 XXX111
1 XXX 112 XXX112
2 YYY 222 yyy222
2 YYY 333 yyy112
SQL> Sofar good. Now i want to replace the TABLE(XMLSEQUENCE) with XMLTABLE operator. I got success with the usage of one XMLTABLE. But when i have requirement for 2, i.e collection within a collection i could not succeed.
here is the one i tried.
select
deptid, dname, empid, ename
from xml
,xmltable('/DeptList/Dept' passing xmltype(data)
columns
deptid number path '/Dept/@id'
,dname varchar2(20) path '/Dept/name') a
,xmltable('/Dept/EMP' passing value(a)
columns
empid number path '/EMP/@id'
,ename varchar2(20) path '/EMP/name')
/How can i make reference to the first collection output to pass it on to the next one.The following demonstrates using XMLTABLE with a Nested Collection
SQL> create or replace view DEPARTMENTS_XML of XMLType
2 with object id
3 (
4 'DEPARTEMENTS'
5 )
6 as
7 select xmlElement
8 (
9 "Departments",
10 xmlAgg
11 (
12 xmlElement
13 (
14 "Department",
15 xmlAttributes( d.DEPARTMENT_ID as "DepartmentId"),
16 xmlElement("Name", d.DEPARTMENT_NAME),
17 xmlElement
18 (
19 "Location",
20 xmlForest
21 (
22 STREET_ADDRESS as "Address", CITY as "City", STATE_PROVINCE as "State",
23 POSTAL_CODE as "Zip",COUNTRY_NAME as "Country"
24 )
25 ),
26 xmlElement
27 (
28 "EmployeeList",
29 (
30 select xmlAgg
31 (
32 xmlElement
33 (
34 "Employee",
35 xmlAttributes ( e.EMPLOYEE_ID as "employeeNumber" ),
36 xmlForest
37 (
38 e.FIRST_NAME as "FirstName", e.LAST_NAME as "LastName", e.EMAIL as "EmailAddress",
39 e.PHONE_NUMBER as "Telephone", e.HIRE_DATE as "StartDate", j.JOB_TITLE as "JobTitle",
40 e.SALARY as "Salary", m.FIRST_NAME || ' ' || m.LAST_NAME as "Manager"
41 ),
42 xmlElement ( "Commission", e.COMMISSION_PCT )
43 )
44 )
45 from HR.EMPLOYEES e, HR.EMPLOYEES m, HR.JOBS j
46 where e.DEPARTMENT_ID = d.DEPARTMENT_ID
47 and j.JOB_ID = e.JOB_ID
48 and m.EMPLOYEE_ID = e.MANAGER_ID
49 )
50 )
51 )
52 )
53 ) as XML
54 from HR.DEPARTMENTS d, HR.COUNTRIES c, HR.LOCATIONS l
55 where d.LOCATION_ID = l.LOCATION_ID
56 and l.COUNTRY_ID = c.COUNTRY_ID
57 /
View created.
SQL> set lines 140
SQL> set long 4000
SQL> --
SQL> select * from DEPARTMENTS_XML
2 /
SYS_NC_ROWINFO$
<Departments><Department DepartmentId="60"><Name>IT</Name><Location><Address>2014 Jabberwocky Rd</Address><City>Southlake</City><St
</State><Zip>26192</Zip><Country>United States of America</Country></Location><EmployeeList><Employee employeeNumber="103"><FirstNa
der</FirstName><LastName>Hunold</LastName><EmailAddress>AHUNOLD</EmailAddress><Telephone>590.423.4567</Telephone><StartDate>1990-01
tDate><JobTitle>Programmer</JobTitle><Salary>9000</Salary><Manager>Lex De Haan</Manager><Commission></Commission></Employee><Employ
eeNumber="105"><FirstName>David</FirstName><LastName>Austin</LastName><EmailAddress>DAUSTIN</EmailAddress><Telephone>590.423.4569</
<StartDate>1997-06-25</StartDate><JobTitle>Programmer</JobTitle><Salary>4800</Salary><Manager>Alexander Hunold</Manager><Commissio
ssion></Employee><Employee employeeNumber="106"><FirstName>Valli</FirstName><LastName>Pataballa</LastName><EmailAddress>VPATABAL</E
ss><Telephone>590.423.4560</Telephone><StartDate>1998-02-05</StartDate><JobTitle>Programmer</JobTitle><Salary>4800</Salary><Manager
r Hunold</Manager><Commission></Commission></Employee><Employee employeeNumber="107"><FirstName>Diana</FirstName><LastName>Lorentz<
<EmailAddress>DLORENTZ</EmailAddress><Telephone>590.423.5567</Telephone><StartDate>1999-02-07</StartDate><JobTitle>Programmer</Job
lary>4200</Salary><Manager>Alexander Hunold</Manager><Commission></Commission></Employee><Employee employeeNumber="104"><FirstName>
SYS_NC_ROWINFO$
rstName><LastName>Ernst</LastName><EmailAddress>BERNST</EmailAddress><Telephone>590.423.4568</Telephone><StartDate>1991-05-21</Star
bTitle>Programmer</JobTitle><Salary>6000</Salary><Manager>Alexander Hunold</Manager><Commission></Commission></Employee></EmployeeL
artment><Department DepartmentId="50"><Name>Shipping</Name><Location><Address>2011 Interiors Blvd</Address><City>South San Francisc
State>California</State><Zip>99236</Zip><Country>United States of America</Country></Location><EmployeeList><Employee employeeNumbe
FirstName>Matthew</FirstName><LastName>Weiss</LastName><EmailAddress>MWEISS</EmailAddress><Telephone>650.123.1234</Telephone><Start
-07-18</StartDate><JobTitle>Stock Manager</JobTitle><Salary>8000</Salary><Manager>Steven King</Manager><Commission></Commission></E
Employee employeeNumber="122"><FirstName>Payam</FirstName><LastName>Kaufling</LastName><EmailAddress>PKAUFLIN</EmailAddress><Teleph
23.3234</Telephone><StartDate>1995-05-01</StartDate><JobTitle>Stock Manager</JobTitle><Salary>7900</Salary><Manager>Steven King</Ma
mmission></Commission></Employee><Employee employeeNumber="121"><FirstName>Adam</FirstName><LastName>Fripp</LastName><EmailAddress>
mailAddress><Telephone>650.123.2234</Telephone><StartDate>1997-04-10</StartDate><JobTitle>Stock Manager</JobTitle><Salary>8200</Sal
ger>Steven King</Manager><Commission></Commission></Employee><Employee employeeNumber="124"><FirstName>Kevin</FirstName><LastName>M
SYS_NC_ROWINFO$
astName><EmailAddress>KMOURGOS</EmailAddress><Telephone>650.123.5234</Telephone><StartDate>1999-11-16</StartDate><JobTitle>Stock Ma
bTitle><Salary>5800</Salary><Manager>Steven King</Manager><Commission></Commission></Employee><Employee employeeNumber="123"><First
ta</FirstName><LastName>Vollman</LastName><EmailAddress>SVOLLMAN</EmailAddress><Telephone>650.123.4234</Telephone><StartDate>1997-1
rtDate><JobTitle>Stock Manager</JobTitle><Salary>6500</Salary><Manager>Steven King</Manager><Commission></Commission></Employee><Em
ployeeNumber="128"><FirstName>Steven</FirstName><LastName>Markle</LastName><EmailAddress>SMARKLE</EmailAddress><Telephone>650.124.1
phone><StartDate>2000-03-08</StartDate><JobTitle>Stock Clerk</JobTitle><Salary>2200</Salary><Manager>Matthew Weiss</Manager><Commis
mmission></Employee><Employee employeeNumber="127"><FirstName>James</FirstName><
SQL> select d.DEPARTMENT_ID, d.DEPARTMENT_NAME, e.*
2 from DEPARTMENTS_XML,
3 xmltable
4 (
5 '/Departments/Department'
6 passing object_value
7 columns
8 DEPARTMENT_ID number(4) path '@DepartmentId',
9 DEPARTMENT_NAME varchar2(32) path 'Name',
10 EMPLOYEES xmlType path 'EmployeeList/Employee'
11 ) d,
12 xmlTable
13 (
14 '/Employee'
15 passing d.EMPLOYEES
16 columns
17 EMPLOYEE_ID number path '@employeeNumber',
18 FIRST_NAME varchar2(32) path 'FirstName',
19 LAST_NANE varchar2(32) path 'LastName'
20 ) e
21 /
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
60 IT 103 Alexander Hunold
60 IT 105 David Austin
60 IT 106 Valli Pataballa
60 IT 107 Diana Lorentz
60 IT 104 Bruce Ernst
50 Shipping 120 Matthew Weiss
50 Shipping 122 Payam Kaufling
50 Shipping 121 Adam Fripp
50 Shipping 124 Kevin Mourgos
50 Shipping 123 Shanta Vollman
50 Shipping 128 Steven Markle
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
50 Shipping 127 James Landry
50 Shipping 126 Irene Mikkilineni
50 Shipping 125 Julia Nayer
50 Shipping 180 Winston Taylor
50 Shipping 181 Jean Fleaur
50 Shipping 182 Martha Sullivan
50 Shipping 183 Girard Geoni
50 Shipping 129 Laura Bissot
50 Shipping 130 Mozhe Atkinson
50 Shipping 131 James Marlow
50 Shipping 132 TJ Olson
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
50 Shipping 184 Nandita Sarchand
50 Shipping 185 Alexis Bull
50 Shipping 186 Julia Dellinger
50 Shipping 187 Anthony Cabrio
50 Shipping 133 Jason Mallin
50 Shipping 134 Michael Rogers
50 Shipping 135 Ki Gee
50 Shipping 136 Hazel Philtanker
50 Shipping 188 Kelly Chung
50 Shipping 189 Jennifer Dilly
50 Shipping 190 Timothy Gates
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
50 Shipping 191 Randall Perkins
50 Shipping 137 Renske Ladwig
50 Shipping 140 Joshua Patel
50 Shipping 139 John Seo
50 Shipping 138 Stephen Stiles
50 Shipping 192 Sarah Bell
50 Shipping 193 Britney Everett
50 Shipping 194 Samuel McCain
50 Shipping 195 Vance Jones
50 Shipping 144 Peter Vargas
50 Shipping 143 Randall Matos
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
50 Shipping 142 Curtis Davies
50 Shipping 141 Trenna Rajs
50 Shipping 196 Alana Walsh
50 Shipping 199 Douglas Grant
50 Shipping 197 Kevin Feeney
50 Shipping 198 Donald OConnell
10 Administration 200 Jennifer Whalen
30 Purchasing 114 Den Raphaely
30 Purchasing 118 Guy Himuro
30 Purchasing 117 Sigal Tobias
30 Purchasing 119 Karen Colmenares
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
30 Purchasing 115 Alexander Khoo
30 Purchasing 116 Shelli Baida
90 Executive 101 Neena Kochhar
90 Executive 102 Lex De Haan
100 Finance 108 Nancy Greenberg
100 Finance 112 Jose Manuel Urman
100 Finance 111 Ismael Sciarra
100 Finance 113 Luis Popp
100 Finance 109 Daniel Faviet
100 Finance 110 John Chen
110 Accounting 206 William Gietz
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
110 Accounting 205 Shelley Higgins
20 Marketing 202 Pat Fay
20 Marketing 201 Michael Hartstein
40 Human Resources 203 Susan Mavris
80 Sales 148 Gerald Cambrault
80 Sales 149 Eleni Zlotkey
80 Sales 145 John Russell
80 Sales 146 Karen Partners
80 Sales 147 Alberto Errazuriz
80 Sales 150 Peter Tucker
80 Sales 151 David Bernstein
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
80 Sales 152 Peter Hall
80 Sales 153 Christopher Olsen
80 Sales 154 Nanette Cambrault
80 Sales 155 Oliver Tuvault
80 Sales 161 Sarath Sewall
80 Sales 160 Louise Doran
80 Sales 159 Lindsey Smith
80 Sales 158 Allan McEwen
80 Sales 157 Patrick Sully
80 Sales 156 Janette King
80 Sales 167 Amit Banda
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
80 Sales 166 Sundar Ande
80 Sales 165 David Lee
80 Sales 164 Mattea Marvins
80 Sales 163 Danielle Greene
80 Sales 162 Clara Vishney
80 Sales 173 Sundita Kumar
80 Sales 172 Elizabeth Bates
80 Sales 171 William Smith
80 Sales 170 Tayler Fox
80 Sales 169 Harrison Bloom
80 Sales 168 Lisa Ozer
DEPARTMENT_ID DEPARTMENT_NAME EMPLOYEE_ID FIRST_NAME LAST_NANE
80 Sales 177 Jack Livingston
80 Sales 176 Jonathon Taylor
80 Sales 175 Alyssa Hutton
80 Sales 174 Ellen Abel
80 Sales 179 Charles Johnson
70 Public Relations 204 Hermann Baer
105 rows selected.
SQL> -
Concatenate elements with same name in sequence
version 9.2
I have a clob column containing xml - unregistered
Some of the old xml has multiple <notes> elements and the new xml has one <notes> element. I have made a view that successfully extracts the xml from the column and it works great, but when I have multiple <notes> elements the view fails since I am using extractvalue(). I need to select the <notes> tags concatenated into one column in sequence when I have multiples. I am guessing the sequence should be as they appear in the xml document from top to bottom since there is no sequence attribute. I know how to use xmlsequence and xmltable to get the individual <notes> tags but they are not concatenated. Is there a magic xmlsequence/concatenation function that will do what I want here?
-- old xml
<Accident>
<Case>
<TRACS_Case_Number Value="7777777"/>
<Notes>V-1 AND V-2 N/B TRANSIT RD (ST 78\) SLOWING TO MERGE INTO TRAFFIC. V-3 N/B TRANSIT RD. </Notes>
<Notes>STRIKES V-2 IN REAR AND PUSHES V-2 INTO V-1 STRIKING V-1 IN REAR WITH FRONT OF V-2 . </Notes>
<Notes>NO INJURIES.</Notes>
</Case>
</Accident>-- new xml
<Accident>
<Case>
<TRACS_Case_Number Value="7777777"/>
<Notes>V-1 AND V-2 N/B TRANSIT RD (ST 78) SLOWING TO MERGE INTO TRAFFIC. V-3 N/B TRANSIT RD. STRIKES V-2 IN REAR AND PUSHES V-2 INTO V-1 STRIKING V-1 IN REAR WITH FRONT OF V-2 . NO INJURIES.</Notes>
</Case>
</Accident>I am also trying to register this xml to improve performance. However, when I see things like this in the xml I wonder what will happen when I try to register this xml. The DTD, I have no XSD, currently only supports one <notes> tag. Do I have to clean up all the xml in column to match the current DTD before registering? I could also use a good, EASY, example of how to register a schema.
Thanks...You can use the string aggregation technique to concatenate the Notes element.
sql> WITH xmltable AS
2 (SELECT xmltype('<Accident>
3 <Case>
4 <TRACS_Case_Number Value="7777777"/>
5 <Notes>V-1 AND V-2 N/B TRANSIT RD (ST 78\) SLOWING TO MERGE INTO TRAFFIC. V-3 N/B TRANSIT RD. </Notes>
6 <Notes>STRIKES V-2 IN REAR AND PUSHES V-2 INTO V-1 STRIKING V-1 IN REAR WITH FRONT OF V-2 . </Notes>
7 <Notes>NO INJURIES.</Notes>
8 </Case>
9 </Accident>') xmlcol
10 FROM dual)
11 SELECT SUBSTR(replace(MAX(sys_connect_by_path(notes, ':')),':',' '), 2) Notes
12 FROM
13 (SELECT extractvalue(t.column_value, '/Notes/text()') notes,
14 rownum rn
15 FROM xmltable xt,
16 TABLE(xmlsequence(EXTRACT(xmlcol, 'Accident/Case/Notes'))) t)
17 CONNECT BY PRIOR rn = rn -1 START WITH rn = 1;
NOTES
V-1 AND V-2 N/B TRANSIT RD (ST 78\) SLOWING TO MERGE INTO TRAFFIC. V-3 N/B TRANSIT RD. STRIKES V-2 IN REAR AND PUSHES
G V-1 IN REAR WITH FRONT OF V-2 . NO INJURIES. -
Transform old table(xmlsequence) to modern XMLTABLE
Hi,
could You please help with translating
SELECT SSS_task_id, extractValue(value(taskhist),'/task/taskId') taskId,
extractValue(value(taskhist), '/task/id') id_,
extractValue(value(typeId), '/typeId') typeId,
rownum wiersz FROM
sss_archive2,
TABLE(xmlsequence(extract(xmltype(SSS_archive2.SSS_data2),'/ns2:ArchivisedTask/taskHistory/task','xmlns:ns2="http://some.com/qservice/model" xmlns:ns3="http://some.com/qservice/method"'))) taskhist,
TABLE (xmlsequence(extract(value(taskhist),'/task/typeId'))) typeId
where
SSS_task_id=extractValue(value(taskhist), '/task/taskId')
and SSS_audit_st=1to XMLTABLE query .
And is that enought to improve performance or is it rather style only change .
currently I've got plan like:
create table ARH_2 as
SELECT SSS_task_id, extractValue(value(taskhist),'/task/taskId') taskId,
extractValue(value(taskhist), '/task/id') id_,
extractValue(value(typeId), '/typeId') typeId,
rownum wiersz FROM
sss_archive2,
TABLE(xmlsequence(extract(xmltype(SSS_archive2.SSS_data2),'/ns2:ArchivisedTask/taskHistory/task','xmlns:ns2="http://some.com/qservice/model" xmlns:ns3="http://some.com/qservice/method"'))) taskhist,
TABLE (xmlsequence(extract(value(taskhist),'/task/typeId'))) typeId
where
SSS_task_id=extractValue(value(taskhist), '/task/taskId')
and SSS_audit_st=1
Plan hash value: 2424165471
| Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem |
| 1 | LOAD AS SELECT | | | 519K| 519K| 519K (0)|
| 2 | COUNT | | | | | |
| 3 | NESTED LOOPS | | 267M| | | |
| 4 | NESTED LOOPS | | 16360 | | | |
|* 5 | TABLE ACCESS FULL | SSS_ARCHIVE2 | 631K| | | |
|* 6 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | | | | |
| 7 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
Predicate Information (identified by operation id):
5 - filter("SSS_AUDIT_ST"=1)
6 - filter("SSS_TASK_ID"=EXTRACTVALUE(VALUE(KOKBF$),'/task/taskId'))
Note
- dynamic sampling used for this statement
- Warning: basic plan statistics not available. These are only collected when:
* hint 'gather_plan_statistics' is used for the statement or
* parameter 'statistics_level' is set to 'ALL', at session or system levelHere are 2 ways to rewrite the XMLSEQUENCE
SQL> set autotrace on explain pages 50 lines 160 trimspool on
SQL> --
SQL> select SSS_TASK_ID, TASK_ID, ID_, TYPE_ID, ROWNUM WIERSZ
2 from sss_archive2,
3 XMLTABLE
4 (
5 xmlnamespaces
6 (
7 'http://some.com/qservice/model' as "ns2",
8 'http://some.com/qservice/method' as "ns3"
9 ),
10 '/ns2:ArchivisedTask/taskHistory/task'
11 passing SSS_data2
12 COLUMNS
13 TASK_ID NUMBER(2) path 'taskId',
14 ID_ NUMBER(2) path 'id',
15 TYPE_ID_XML XMLTYPE path 'typeId'
16 ),
17 XMLTABLE
18 (
19 xmlnamespaces
20 (
21 'http://some.com/qservice/model' as "ns2",
22 'http://some.com/qservice/method' as "ns3"
23 ),
24 '/typeId'
25 passing TYPE_ID_XML
26 columns
27 TYPE_ID NUMBER(2) path '.'
28 )
29 where TASK_ID = SSS_task_id
30 and SSS_audit_st=1
31 /
no rows selected
Elapsed: 00:00:00.00
Execution Plan
Plan hash value: 3547186508
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 2036 | 60 (0)| 00:00:01 |
| 1 | COUNT | | | | | |
| 2 | NESTED LOOPS | | 1 | 2036 | 60 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 1 | 2034 | 31 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| SSS_ARCHIVE2 | 1 | 2028 | 2 (0)| 00:00:01 |
|* 5 | XPATH EVALUATION | | | | | |
| 6 | XPATH EVALUATION | | | | | |
Predicate Information (identified by operation id):
4 - filter("SSS_AUDIT_ST"=1)
5 - filter("SSS_TASK_ID"=CAST(TO_NUMBER("P"."C_02$") AS NUMBER(2) ))
Note
- dynamic sampling used for this statement (level=2)
SQL> select SSS_TASK_ID, TASK_ID, ID_, TYPE_ID, ROWNUM WIERSZ
2 from sss_archive2,
3 XMLTABLE
4 (
5 'declare namespace ns2="http://some.com/qservice/model"; (: :)
6 declare namespace ns3="http://some.com/qservice/method"; (: :)
7 for $TASK in $XML/ns2:ArchivisedTask/taskHistory/task[taskId=$TASK_ID]
8 for $TYPE in $TASK/typeId
9 return
10 <RESULT>
11 {
12 $TASK/taskId,
13 $TASK/id,
14 $TYPE/typeId
15 }
16 </RESULT>'
17 passing SSS_data2 as "XML", SSS_TASK_ID as "TASK_ID"
18 COLUMNS
19 TASK_ID NUMBER(2) path 'taskId',
20 ID_ NUMBER(2) path 'id',
21 TYPE_ID NUMBER(2) path 'typeId'
22 )
23 /
no rows selected
Elapsed: 00:00:00.05
Execution Plan
Plan hash value: 3773532344
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 2029 | 89 (0)| 00:00:02 |
| 1 | COUNT | | | | | |
| 2 | NESTED LOOPS SEMI | | 1 | 2029 | 89 (0)| 00:00:02 |
| 3 | NESTED LOOPS | | 1 | 2027 | 60 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 2025 | 31 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL| SSS_ARCHIVE2 | 1 | 2015 | 2 (0)| 00:00:01 |
| 6 | XPATH EVALUATION | | | | | |
| 7 | XPATH EVALUATION | | | | | |
|* 8 | XPATH EVALUATION | | | | | |
Predicate Information (identified by operation id):
8 - filter(TO_BINARY_DOUBLE("P2"."C_01$")=TO_BINARY_DOUBLE("SSS_TASK_ID"))
Note
- dynamic sampling used for this statement (level=2)
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)
SQL>
SQL>The first is more SQL Centric, the second is more XQUERY centric.. They should be equivialnt in turns of efficiency -
XMLTable performance vs. TABLE(XMLSequence())
Hi everybody,
I've faced an issue that I hope I can find help with.
There's a task to parse a large (~15 MB) XML text and update a table based on it. So I've created a procedure that takes one XMLType parameter and does the job. Pretty straightforward. However, the thing is that, if I use XMLTable, which is the preferred method, to parse the XML, it runs for hours. Once I replace XMLTable with TABLE(XMLSequence()) method, the procedure completes in under two minutes on the same machine. Looks very strange to me.
Any ideas what could be causing such a poor performance of XMLTable?
Oracle version is 11.2.0.2.0
h1. Table structure
create table Points (
member_id int not null,
point_id int,
country_numeric character(3),
place national character varying(50),
name national character varying(255),
currencies national character varying(255),
address national character varying(255),
contact national character varying(40),
contact_phone national character varying(40),
details national character varying(255),
enabled_date date,
works national character varying(255),
active character default 1 check (active in (0, 1)) not null,
unique (member_id, point_id)
);h1. XMLTable method
runs for many hours if input parameter is ~15 MB long
create procedure update_Points (
p_Points in xmltype
) as
begin
insert into Points (member_id, point_id, country_numeric, place, name, currencies, address, contact, contact_phone, details, enabled_date, works)
select
ap.member_id,
ap.point_id,
ap.country_numeric,
ap.place,
ap.name,
ap.currencies,
ap.address,
ap.contact,
ap.contact_phone,
ap.details,
to_date(ap.enabled_date, 'DD.MM.YYYY'),
ap.works
from
xmltable('for $Point in /document/directory/reply[@type=''Points'']/data/row return element Point { attribute member_id { $Point/column[@col=''1'']/@value }, attribute point_id { $Point/column[@col=''2'']/@value }, attribute country_numeric { $Point/column[@col=''3'']/@value }, attribute place { $Point/column[@col=''4'']/@value }, attribute name { $Point/column[@col=''5'']/@value }, attribute currencies { $Point/column[@col=''6'']/@value }, attribute address { $Point/column[@col=''7'']/@value }, attribute contact { $Point/column[@col=''8'']/@value }, attribute contact_phone { $Point/column[@col=''9'']/@value }, attribute details { $Point/column[@col=''10'']/@value }, attribute enabled_date { $Point/column[@col=''11'']/@value }, attribute works { $Point/column[@col=''12'']/@value } }'
passing p_Points
columns
member_id int path '@member_id',
point_id int path '@point_id',
country_numeric character(3) path '@country_numeric',
place national character varying(50) path '@place',
name national character varying(255) path '@name',
currencies national character varying(255) path '@currencies',
address national character varying(255) path '@address',
contact national character varying(40) path '@contact',
contact_phone national character varying(40) path '@contact_phone',
details national character varying(255) path '@details',
enabled_date character(10) path '@enabled_date',
works national character varying(255) path '@works') ap;
end;h1. TABLE(XMLSequence()) method
runs for 2 minutes with the same input parameter
create procedure update_Points (
p_Points in xmltype
) as
begin
insert into Points (member_id, point_id, country_numeric, place, name, currencies, address, contact, contact_phone, details, enabled_date, works)
select
value(x).extract('row/column[@col=''1'']/@value').getStringVal() member_id,
value(x).extract('row/column[@col=''2'']/@value').getStringVal() point_id,
value(x).extract('row/column[@col=''3'']/@value').getStringVal() country_numeric,
value(x).extract('row/column[@col=''4'']/@value').getStringVal() place,
extractValue(value(x), '/row/column[@col=''5'']/@value') name,
value(x).extract('row/column[@col=''6'']/@value').getStringVal() currencies,
value(x).extract('row/column[@col=''7'']/@value').getStringVal() address,
value(x).extract('row/column[@col=''8'']/@value').getStringVal() contact,
value(x).extract('row/column[@col=''9'']/@value').getStringVal() contact_phone,
value(x).extract('row/column[@col=''10'']/@value').getStringVal() details,
to_date(value(x).extract('row/column[@col=''11'']/@value').getStringVal(), 'DD.MM.YYYY') enabled_date,
value(x).extract('row/column[@col=''12'']/@value').getStringVal() works
from
table(xmlsequence(extract(p_Points, '/document/directory/reply[@type=''Points'']/data/row'))) x;
end;h1. Small XML sample
<?xml version="1.0"?>
<document>
<directory>
<reply type="Points">
<data>
<row>
<column col="1" value="0"></column>
<column col="2" value=""></column>
<column col="3" value="643"></column>
<column col="4" value="Something"></column>
<column col="5" value=""Sample""></column>
<column col="6" value=""></column>
<column col="7" value="Blah"></column>
<column col="8" value="Bar"></column>
<column col="9" value="0123456789"></column>
<column col="10" value=""></column>
<column col="11" value="01.01.2010"></column>
<column col="12" value=""></column>
</row>
</data>
</reply>
</directory>
</document>Edited by: 999663 on Apr 15, 2013 1:21 PModie_63 wrote:
>LOL - Should have known :-)
After a fresh start of my database, it shows the following...
SQL> select count(*) from user_objects;
COUNT(*)
530
SQL> var doc clob
exec :doc := dbms_xmlgen.getxml('select * from user_objects')SQL>
PL/SQL procedure successfully completed.
SQL> set autotrace traceonly
set timing on
set pages 100
set lines 200
SQL> SQL> SQL> SQL>
SQL>
SQL> select *
from xmltable(
'for $i in /ROWSET/ROW
return element r {
element object_name {$i/OBJECT_NAME/text()}
, element object_type {$i/OBJECT_TYPE/text()}
, element status {$i/STATUS/text()}
passing xml 2 3 4 5 6 7 8 9 parse(document :doc)
columns object_name varchar2(30) path 'object_name'
, object_type varchar2(19) path 'object_type'
, status varchar2(7) path 'status'
) ; 10 11 12 13
530 rows selected.
Elapsed: 00:00:01.02
Execution Plan
Plan hash value: 3781821901
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 49008 | 29 (0)| 00:00:01 |
| 1 | XMLTABLE EVALUATION | | | | | |
Statistics
636 recursive calls
1041 db block gets
1991 consistent gets
35 physical reads
0 redo size
19539 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
30 sorts (memory)
0 sorts (disk)
530 rows processed
SQL> select *
from xmltable(
'/ROWSET/ROW'
passing xmlparse(document :doc)
columns object_name varchar2(30) path 'OBJECT_NAME'
, object_type varchar2(19) path 'OBJECT_TYPE'
, status varchar2(7) path 'STATUS'
2 3 4 5 6 7 8 ) ;
530 rows selected.
Elapsed: 00:00:00.06
Execution Plan
Plan hash value: 3781821901
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 49008 | 29 (0)| 00:00:01 |
| 1 | XMLTABLE EVALUATION | | | | | |
Statistics
2 recursive calls
1041 db block gets
741 consistent gets
0 physical reads
0 redo size
19539 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
530 rows processed
SQL> select extractvalue(value(t), '/ROW/OBJECT_NAME')
, extractvalue(value(t), '/ROW/OBJECT_TYPE')
, extractvalue(value(t), '/ROW/STATUS')
from table(
xmlsequence(
extract(xmltype(:doc), '/ROWSET/ROW')
) t ; 2 3 4 5 6 7 8
530 rows selected.
Elapsed: 00:00:00.27
Execution Plan
Plan hash value: 1186311642
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 16336 | 29 (0)| 00:00:01 |
| 1 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | 8168 | 16336 | 29 (0)| 00:00:01 |
Note
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)
Statistics
12 recursive calls
2162 db block gets
847 consistent gets
0 physical reads
0 redo size
19629 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
530 rows processed
SQL>
SQL>
SQL> -- STUFF BEING NOW CACHED ---
SQL>
SQL>
SQL>
select *
from xmltable(
'for $i in /ROWSET/ROW
return element r {
element object_name {$i/OBJECT_NAME/text()}
, element object_type {$i/OBJECT_TYPE/text()}
, element status {$i/STATUS/text()}
passing xmSQL> 2 3 4 5 6 7 8 9 lparse(document :doc)
columns object_name varchar2(30) path 'object_name'
, object_type varchar2(19) path 'object_type'
, status varchar2(7) path 'status'
select *
from xmltable(
'/ROWSET/ROW'
10 11 12 13 passing xmlparse(document :doc)
columns object_name varchar2(30) path 'OBJECT_NAME'
, object_type varchar2(19) path 'OBJECT_TYPE'
, status varchar2(7) path 'STATUS'
select extractvalue(value(t), '/ROW/OBJECT_NAME')
, extractvalue(value(t), '/ROW/OBJECT_TYPE')
, extractvalue(value(t), '/ROW/STATUS')
from table(
xmlsequence(
extract(xmltype(:doc), '/ROWSET/ROW')
) t ;
530 rows selected.
Elapsed: 00:00:00.06
Execution Plan
Plan hash value: 3781821901
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 49008 | 29 (0)| 00:00:01 |
| 1 | XMLTABLE EVALUATION | | | | | |
Statistics
0 recursive calls
1041 db block gets
553 consistent gets
0 physical reads
0 redo size
19539 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
530 rows processed
SQL> SQL> SQL> 2 3 4 5 6 7 8
530 rows selected.
Elapsed: 00:00:00.05
Execution Plan
Plan hash value: 3781821901
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 49008 | 29 (0)| 00:00:01 |
| 1 | XMLTABLE EVALUATION | | | | | |
Statistics
0 recursive calls
1041 db block gets
553 consistent gets
0 physical reads
0 redo size
19539 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
530 rows processed
SQL> SQL> SQL> 2 3 4 5 6 7 8
530 rows selected.
Elapsed: 00:00:00.25
Execution Plan
Plan hash value: 1186311642
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 16336 | 29 (0)| 00:00:01 |
| 1 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | 8168 | 16336 | 29 (0)| 00:00:01 |
Note
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)
Statistics
0 recursive calls
2162 db block gets
637 consistent gets
0 physical reads
0 redo size
19629 bytes sent via SQL*Net to client
929 bytes received via SQL*Net from client
37 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
530 rows processedXQuery FLWOR : 00:00:00.06
XQuery XPath : 00:00:00.05
XMLSeq XPath : 00:00:00.25
As I said, Oracle' statement of Direction was that it would become "deprecated", the moment it officially is mentioned in the docs, you will see less and less effort in maintaining (in this case) the propriety methods...
M. -
Cartesian Join of xmltables.
Hi,
SQL> var xml varchar2(3999)
SQL> begin
2 :xml := '<X12 NAME="856.edi">
3 <ISA01>00</ISA01>
4 <ISA02>XXXXXXXXXX</ISA02>
5 <ISA03>00</ISA03>
6 <ISA04>XXXXXXXXXX</ISA04>
7 <ISA05>ZZ</ISA05>
8 <ISA ID="552101">
9 <GS01>SH</GS01>
10 <GS02>xxxxxxxx</GS02>
11 <GS03>xxxxxxxxx</GS03>
12 <GS04>20060815</GS04>
13 <GS05>015219</GS05>
14 <GS06>xxxxxxxxxx</GS06>
15 <GS07>X</GS07>
16 <GS08>004010</GS08>
17 <GS ID="552102">
18 <ST01>856</ST01>
19 <ST02>0001</ST02>
20 <ST ID="552103">
21 <LIN>
22 <LIN02>IN</LIN02>
23 <LIN03>9D00025443</LIN03>
24 <LIN04>PO</LIN04>
25 <LIN05>25254404</LIN05>
26 </LIN>
27 <SN1>
28 <SN102>552</SN102>
29 <SN103>EA</SN103>
30 </SN1>
31 <LIN>
32 <LIN02>IN</LIN02>
33 <LIN03>9D00025443</LIN03>
34 <LIN04>PO</LIN04>
35 <LIN05>25255149</LIN05>
36 </LIN>
37 <SN1>
38 <SN102>1104</SN102>
39 <SN103>EA</SN103>
40 </SN1>
41 <CTT>
42 <CTT01>9</CTT01>
43 </CTT>
44 <SE>
45 <SE01>38</SE01>
46 <SE02>0001</SE02>
47 </SE>
48 </ST>
49 </GS>
50 <GE>
51 <GE01>1</GE01>
52 <GE02>913823084</GE02>
53 </GE>
54 <IEA>
55 <IEA01>1</IEA01>
56 <IEA02>913823084</IEA02>
57 </IEA>
58 </ISA>
59 </X12>';
60 end;
61 /
PL/SQL procedure successfully completed.
SQL> set long 32000
SQL> SELECT VALUE (i).EXTRACT ('/*')
2 FROM
3 TABLE (XMLSEQUENCE (EXTRACT (XMLTYPE (:xml), '/X12/ISA/GS/ST'))) k,
4 TABLE (XMLSEQUENCE (EXTRACT (VALUE (k), '/ST/LIN'))) i;
VALUE(I).EXTRACT('/*')
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25254404</LIN05>
</LIN>
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25255149</LIN05>
</LIN>
SQL>
SQL> SELECT VALUE (i).EXTRACT ('/*')
2 FROM
3 TABLE (XMLSEQUENCE (EXTRACT (XMLTYPE (:xml), '/X12/ISA/GS/ST'))) k,
4 TABLE (XMLSEQUENCE (EXTRACT (VALUE (k), '/ST/LIN'))) i,
5 TABLE (XMLSEQUENCE (EXTRACT (VALUE (k), '/ST/SN1'))) m;
VALUE(I).EXTRACT('/*')
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25254404</LIN05>
</LIN>
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25254404</LIN05>
</LIN>
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25255149</LIN05>
</LIN>
<LIN>
<LIN02>IN</LIN02>
<LIN03>9D00025443</LIN03>
<LIN04>PO</LIN04>
<LIN05>25255149</LIN05>
</LIN>I am trying to put the LIN and SN1 segment into one row. But, when I do it this way, it is giving me cartesian join. I tried doing this using XMLTable operator too. I couldn't get anywhere.Look at the example of the manual (XMLDB Developers Guide) regarding the use of XMLQuery and XMLTable: Example 17-12 Using XMLTable to Shred XML Collection Elements into Relational Data
or given the following example, can you work it out now for your situation?
SQL*Plus: Release 10.2.0.2.0 - Production on Tue Oct 10 20:52:53 2006
Copyright (c) 1982, 2005, Oracle. All Rights Reserved.
SQL> @login
SQL> conn oe/[email protected]
Connected.
SQL> select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
5 rows selected.
SQL> CREATE OR REPLACE VIEW purchaseorder_detail_view AS
2 SELECT po.reference, li.*
3 FROM purchaseorder p,
4 XMLTable('/PurchaseOrder' PASSING p.OBJECT_VALUE
5 COLUMNS
6 reference VARCHAR2(30) PATH 'Reference',
7 lineitem XMLType PATH 'LineItems/LineItem') po,
8 XMLTable('LineItem' PASSING po.lineitem
9 COLUMNS
10 itemno NUMBER(38) PATH '@ItemNumber',
11 description VARCHAR2(256) PATH 'Description',
12 partno VARCHAR2(14) PATH 'Part/@Id',
13 quantity NUMBER(12, 2) PATH 'Part/@Quantity',
14 unitprice NUMBER(8, 4) PATH 'Part/@UnitPrice') li;
View created.
SQL> desc purchaseorder_detail_view
Name Null? Type
REFERENCE VARCHAR2(30)
ITEMNO NUMBER(38)
DESCRIPTION VARCHAR2(256)
PARTNO VARCHAR2(14)
QUANTITY NUMBER(12,2)
UNITPRICE NUMBER(8,4)
SQL> select * from purchaseorder_detail_view
1 where rownum <= 10;
REFERENCE ITEMNO DESCRIPTION PARTNO QUANTITY UNITPRICE
CJOHNSON-20021009123337283PDT 1 Rushmore 715515010429 1 39.95
CJOHNSON-20021009123337283PDT 2 The Magic Flute 37429147528 2 29.95
CJOHNSON-20021009123337283PDT 3 How to Get Ahead in Advertising 715515012324 1 29.95
CJOHNSON-20021009123337283PDT 4 Written on the Wind 715515011525 3 29.95
CJOHNSON-20021009123337283PDT 5 Spartacus 715515011723 2 39.96
CJOHNSON-20021009123337283PDT 6 The Hidden Fortress 37429135129 2 29.95
CJOHNSON-20021009123337283PDT 7 Amarcord 37429121825 1 39.95
CJOHNSON-20021009123337283PDT 8 The Harder They Come 715515010825 3 39.95
CJOHNSON-20021009123337283PDT 9 George Washington 37429166123 2 39.95
CJOHNSON-20021009123337283PDT 10 Sanjuro 37429141526 1 29.95
10 rows selected.
Message was edited by:
mgralike -
Newbie- xmlsequence and GROUPING
Below works OK with 1 record. If a person has 2 records, I need it GROUP by DeptOrg
Drop table dummy;
Create table dummy (Pidm number(9,0)
,orgn varchar2(6)
,title varchar2(20)
,Lastname varchar2(20)
,Firstname varchar2(20));
Insert into dummy(pidm,orgn,title,lastname,Firstname)
values(649,'3601','Assoc. VP','Doe','Jane');
Insert into dummy(pidm,orgn,title,lastname,Firstname)
values(649,'3555','Finance Admin','Doe','Jane');
Insert into dummy(pidm,orgn,title,lastname,Firstname)
values(649,'3575','General Expense','Doe','Jane');
Select B.drecord
FROM(
select rpad(t.column_value.getrootelement(),20) || ': ' || t.column_value.extract('//text()') drecord
from table(xmlsequence(xmltype(cursor(select C.Orgn Deptorg,C.* from dummy C where C.pidm=649)).extract('ROWSET/ROW/*'))) t
)B
Order by Lower(B.drecord);
Here is my CURRENT output
DEPTORG : 3555
DEPTORG : 3575
DEPTORG : 3601
FIRSTNAME : Jane
FIRSTNAME : Jane
FIRSTNAME : Jane
LASTNAME : Doe
LASTNAME : Doe
LASTNAME : Doe
ORGN : 3555
ORGN : 3575
ORGN : 3601
PIDM : 649
PIDM : 649
PIDM : 649
TITLE : Assoc. VP
TITLE : Finance Admin
TITLE : General ExpenseBelow is how I WANT my output to be
Deptorg drecord
3555 DEPTORG : 3555
3555 FIRSTNAME : Jane
3555 LASTNAME : Doe
3555 ORGN : 3555
3555 PIDM : 649
3555 TITLE : Finance Admin
3575 DEPTORG : 3575
3575 FIRSTNAME : Jane
3575 LASTNAME : Doe
3575 ORGN : 3575
3575 PIDM : 649
3575 TITLE : General Expense
3601 DEPTORG : 3601
3601 FIRSTNAME : Jane
3601 LASTNAME : Doe
3601 ORGN : 3601
3601 PIDM : 649
3601 TITLE : Assoc. VPI do NOT want to hard code the fields because some fields may be added or deleted in the future.
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
"CORE 10.2.0.4.0 Production"
TNS for 32-bit Windows: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
Can this be done?
TIA.
Steve42Hi Steve,
Since you're on 10.2, you can start using XMLTable and XQuery.
Something like this :
SQL> SELECT x1.deptorg,
2 rpad(x2.col_name,20) || ': ' || x2.col_value as drecord
3 FROM XMLTable(
4 '/ROWSET/ROW'
5 passing dbms_xmlgen.getxmltype('select C.Orgn Deptorg,C.* from dummy C where C.pidm=649')
6 columns deptorg varchar2(30) path 'DEPTORG',
7 cols xmltype path '.'
8 ) x1,
9 XMLTable(
10 'for $i in /ROW/*
11 return element e
12 {
13 attribute name {local-name($i)},
14 $i/text()
15 }'
16 passing x1.cols
17 columns col_name varchar2(30) path '@name',
18 col_value varchar2(30) path '.'
19 ) x2
20 ;
DEPTORG DRECORD
3601 DEPTORG : 3601
3601 PIDM : 649
3601 ORGN : 3601
3601 TITLE : Assoc. VP
3601 LASTNAME : Doe
3601 FIRSTNAME : Jane
3555 DEPTORG : 3555
3555 PIDM : 649
3555 ORGN : 3555
3555 TITLE : Finance Admin
3555 LASTNAME : Doe
3555 FIRSTNAME : Jane
3575 DEPTORG : 3575
3575 PIDM : 649
3575 ORGN : 3575
3575 TITLE : General Expense
3575 LASTNAME : Doe
3575 FIRSTNAME : Jane
18 rows selected -
Hi,
I have the follwing xml in column tmp_xml of table tmp_table:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ses:getCriteriaNamesListResponse xmlns:ses="http://session.kernel.cmp.com/">
<return>
<item>CRITERIA_UID</item>
<item>CRITERIA_LAST_NAME</item>
<item>CRITERIA_MEXI_ADDRESS</item>
<item>CRITERIA_FIRST_NAME</item>
<item>NONE</item>
<item>CRITERIA_NISS</item>
<item>CRITERIA_INAMI</item>
</return>
</ses:getCriteriaNamesListResponse>
</env:Body>
</env:Envelope>
I want to extract all sequences of "item"
This select return 1 empty row:
select extractvalue( value(b), '/env:Envelope/env:Body//return/item', 'xmlns:env="http://schemas.xmlsoap.org/soap/envelope/", xmlns:ses="http://session.kernel.mexi.com/"' ) item
tmp_table a, table(xmlsequence(extract(a.tmp_xml, '//return'))) b
The following select returns 7 empty rows:
select extractvalue( value(b), '/return/item') item
tmp_table a, table(xmlsequence(extract(a.tmp_xml, '/env:Envelope/env:Body//return/item', 'xmlns:env="http://schemas.xmlsoap.org/soap/envelope/", xmlns:ses="http://session.kernel.mexi.com/"'))) b
Could anyone give me a tip how to retrieve the values for "item"?
Regards, HansThank you! This works! Maybe just one more question:
Suppose the following XML:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header/>
<env:Body>
<ses:findAccountByCriteriaResponse xmlns:ses="http://session.kernel.cmp.com/">
<return>
<detailedInfo>Account(s) found: 9</detailedInfo>
<operationResult>MPROXY_RESULT_OK</operationResult>
<value>
<firstName>bernard</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>christophe</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>nele</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>philippe</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>pierre</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>kamiel</firstName>
<lastName>dupont</lastName>
</value>
<value>
<firstName>johan</firstName>
<lastName>dupont</lastName>
</value>
</return>
</ses:findAccountByCriteriaResponse>
</env:Body>
</env:Envelope>
The following sql, again, returns empty rows:
alter session set cursor_sharing=exact
select x.*
tmp_medimail_accounts t
xmltable(
xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as "env", 'http://session.kernel.cmp.com/' as "ses")
, 'env:Envelope/env:Body/ses:findAccountByCriteriaResponse/return/value'
passing t.tmp_xml
columns firstName varchar2(30) path '/firstName',
lastname varchar2(30) path '/lastName' ) x ;
Thank you for the replies! Hans -
Help rewriting this XMLTable query.
Hi,
I rewrote this query:
SELECT VALUE(k) ts_value,
s.transactionsetcontrolnumber ts,
t.xmlintid,
i.isaid,
stid,
g.sendorcode || '!' || g.receivercode || '!' || s.transactionsetid || '!I' geteditpparameter,
EXTRACTVALUE(VALUE(k), '/TS_850/BEG/BEG03') || '-' ||
(SELECT N104
FROM xmltable('/TS_850/GROUP_5/N1' passing VALUE(k) columns N101
VARCHAR2(2) path 'N101',
N104 VARCHAR2(32) path 'N104')
WHERE N101 = 'OB') beg_n104,
g.sendorcode || '!' || g.receivercode || '!' ||
(SELECT N103 || '!' || N104
FROM xmltable('/TS_850/GROUP_5/N1' passing VALUE(k) columns N101
VARCHAR2(2) path 'N101',
N103 VARCHAR2(32) path 'N103',
N104 VARCHAR2(32) path 'N104')
WHERE N101 = 'OB') getedicuststxparameter,
(SELECT to_date(dtm02, 'YYYYMMDD')
FROM xmltable('/TS_850/DTM' passing VALUE(k) columns dtm01
VARCHAR2(3) path 'DTM01',
dtm02 VARCHAR2(32) path 'DTM02')
WHERE DTM01 <> '061') requireddate,
(SELECT SUM(SAC07)
FROM xmltable('/TS_850/GROUP_1/SAC' passing VALUE(k) columns
SAC01 VARCHAR2(2) path 'SAC01',
SAC07 VARCHAR2(32) path 'SAC07')
WHERE SAC01 = 'A') sumsac07
FROM edi_xml_int t,
edi_isa i,
edi_gs g,
edi_st s,
TABLE(XMLSEQUENCE(EXTRACT(x12_850, '/X12/TS_850'))) k
WHERE s.gsid = g.gsid
AND g.isaid = i.isaid
AND t.isaid = i.isaid
AND s.transactionsetcontrolnumber =
EXTRACTVALUE(VALUE(k), '/TS_850/ST/ST02')
AND t.processeddate IS NULL
AND s.transactionsetid = '850'
AND TRIM(i.senderid) = '0722717110100'
and s.updateddate is null order by s.stid;
Explain Plan for this is:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8077 | 16M| 1056 (2)| 00:00:13 |
|* 1 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
|* 2 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
|* 3 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
| 4 | SORT AGGREGATE | | 1 | 2 | | |
|* 5 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | | | | |
| 6 | NESTED LOOPS | | 8077 | 16M| 1056 (2)| 00:00:13 |
| 7 | NESTED LOOPS | | 45 | 95175 | 55 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 45 | 3510 | 4 (0)| 00:00:01 |
| 9 | MERGE JOIN CARTESIAN | | 45 | 2070 | 3 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID | EDI_ST | 45 | 1125 | 2 (0)| 00:00:01 |
| 11 | INDEX FULL SCAN | EDI_ST_PK | 45 | | 1 (0)| 00:00:01 |
| 12 | BUFFER SORT | | 1 | 21 | 1 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | EDI_ISA | 1 | 21 | 1 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | EDI_ISA_IX_1 | 1 | | 0 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | EDI_GS | 1 | 32 | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | EDI_GS_PK | 1 | | 0 (0)| 00:00:01 |
|* 17 | TABLE ACCESS FULL | EDI_XML_INT | 1 | 2037 | 1 (0)| 00:00:01 |
|* 18 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | | | | |
Predicate Information (identified by operation id):
1 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/N101')),50,1,2) AS
VARCHAR2(2) )='OB')
2 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/N101')),50,1,2) AS
VARCHAR2(2) )='OB')
3 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/DTM01')),50,1,2) AS
VARCHAR2(3) )<>'061')
5 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/SAC01')),50,1,2) AS
VARCHAR2(2) )='A')
10 - filter("S"."TRANSACTIONSETID"='850' AND "S"."UPDATEDDATE" IS NULL)
14 - access(TRIM("SENDERID")='0722717110100')
15 - filter("G"."ISAID"="I"."ISAID")
16 - access("S"."GSID"="G"."GSID")
17 - filter("T"."PROCESSEDDATE" IS NULL AND "T"."ISAID"="I"."ISAID")
18 - filter("S"."TRANSACTIONSETCONTROLNUMBER"=EXTRACTVALUE(VALUE(KOKBF$),'/TS_850/ST/ST02'))
Note
- dynamic sampling used for this statement
47 rows selected.I rewrote this to this:
SELECT k.main ts_value,
s.transactionsetcontrolnumber ts,
t.xmlintid,
i.isaid,
stid,
g.sendorcode || '!' || g.receivercode || '!' || s.transactionsetid || '!I' geteditpparameter,
EXTRACTVALUE(k.main, '/TS_850/BEG/BEG03') || '-' ||
(SELECT N104
FROM xmltable('/TS_850/GROUP_5/N1' passing k.main columns N101
VARCHAR2(2) path 'N101',
N104 VARCHAR2(32) path 'N104')
WHERE N101 = 'OB') beg_n104,
g.sendorcode || '!' || g.receivercode || '!' ||
(SELECT N103 || '!' || N104
FROM xmltable('/TS_850/GROUP_5/N1' passing k.main columns N101
VARCHAR2(2) path 'N101',
N103 VARCHAR2(32) path 'N103',
N104 VARCHAR2(32) path 'N104')
WHERE N101 = 'OB') getedicuststxparameter,
(SELECT to_date(dtm02, 'YYYYMMDD')
FROM xmltable('/TS_850/DTM' passing k.main columns dtm01
VARCHAR2(3) path 'DTM01',
dtm02 VARCHAR2(32) path 'DTM02')
WHERE DTM01 <> '061') requireddate,
(SELECT SUM(SAC07)
FROM xmltable('/TS_850/GROUP_1/SAC' passing k.main columns
SAC01 VARCHAR2(2) path 'SAC01',
SAC07 VARCHAR2(32) path 'SAC07')
WHERE SAC01 = 'A') sumsac07
FROM edi_xml_int t,
edi_isa i,
edi_gs g,
edi_st s,
xmltable('/X12/TS_850' passing x12_850 columns main xmltype path
'/TS_850',
st02 varchar2(32) path '/TS_850/ST/ST02') k
WHERE s.gsid = g.gsid
AND g.isaid = i.isaid
AND t.isaid = i.isaid
AND s.transactionsetcontrolnumber = k.st02
AND t.processeddate IS NULL
AND s.transactionsetid = '850'
AND TRIM(i.senderid) = '0722717110100'
and s.updateddate is null
order by s.stid;
Explain plan for this is:
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8077 | 16M| 1056 (2)| 00:00:13 |
|* 1 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
|* 2 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
|* 3 | COLLECTION ITERATOR PICKLER FETCH | XMLSEQUENCEFROMXMLTYPE | | | | |
| 4 | SORT AGGREGATE | | 1 | 2 | | |
|* 5 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | | | | |
| 6 | NESTED LOOPS | | 8077 | 16M| 1056 (2)| 00:00:13 |
| 7 | NESTED LOOPS | | 45 | 95175 | 55 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 45 | 3510 | 4 (0)| 00:00:01 |
| 9 | MERGE JOIN CARTESIAN | | 45 | 2070 | 3 (0)| 00:00:01 |
|* 10 | TABLE ACCESS BY INDEX ROWID | EDI_ST | 45 | 1125 | 2 (0)| 00:00:01 |
| 11 | INDEX FULL SCAN | EDI_ST_PK | 45 | | 1 (0)| 00:00:01 |
| 12 | BUFFER SORT | | 1 | 21 | 1 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | EDI_ISA | 1 | 21 | 1 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | EDI_ISA_IX_1 | 1 | | 0 (0)| 00:00:01 |
|* 15 | TABLE ACCESS BY INDEX ROWID | EDI_GS | 1 | 32 | 1 (0)| 00:00:01 |
|* 16 | INDEX UNIQUE SCAN | EDI_GS_PK | 1 | | 0 (0)| 00:00:01 |
|* 17 | TABLE ACCESS FULL | EDI_XML_INT | 1 | 2037 | 1 (0)| 00:00:01 |
|* 18 | COLLECTION ITERATOR PICKLER FETCH| XMLSEQUENCEFROMXMLTYPE | | | | |
Predicate Information (identified by operation id):
1 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/N101')),50,1,2) AS
VARCHAR2(2) )='OB')
2 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/N101')),50,1,2) AS
VARCHAR2(2) )='OB')
3 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/DTM01')),50,1,2) AS
VARCHAR2(3) )<>'061')
5 - filter(CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALUE(KOKBF$),'/*/SAC01')),50,1,2) AS
VARCHAR2(2) )='A')
10 - filter("S"."TRANSACTIONSETID"='850' AND "S"."UPDATEDDATE" IS NULL)
14 - access(TRIM("SENDERID")='0722717110100')
15 - filter("G"."ISAID"="I"."ISAID")
16 - access("S"."GSID"="G"."GSID")
17 - filter("T"."PROCESSEDDATE" IS NULL AND "T"."ISAID"="I"."ISAID")
18 - filter("S"."TRANSACTIONSETCONTROLNUMBER"=CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQEXTRACT(VALU
E(KOKBF$),'/TS_850/ST/ST02')),50,1,2) AS varchar2(32) ))
Note
- dynamic sampling used for this statement
48 rows selected.Now, I was wondering if you can have just one implementation of XMLTable in the query which will reduce the complexity of this. Both the queries looked like they gave me the same results.
Thank you,
Rahul.It's quite hard to tune a query without seeing the table structure and available indices as well as relationship between each other but I'll try.
In your sql which you've given the table alias AD, you have this filter criteria
AND FIELD_NAME IN (
SELECT FIELD_NAME
FROM APPLICATION_FIELDS
WHERE FIELD_TYPE IN ('Checkbox','Radio','Select','SelectM', 'RadioHoriz','RadioPara')
) </br>
My question is, is FIELD_NAME a column in the APPLICATION_DATA table? If it is, try moving this clause outside of the current sub-query it is in, i.e. one more level up. It looks like you put them inside the wrong level.
I would also try converting this <COL> IN <SUB-QUERY> to a join, if that wouldn't affect the no. of rows returned. I can't tell for sure since I dont know the relationship between your tables.
It looks to me like you're doing this
SELECT <col list>
FROM ( SELECT -- LEVEL 1
FROM APPLICATION_DATA AD
WHERE AD.APPLICAITON_ID IN ( -- LEVEL 2
SELECT
FROM APPLICATIONS A
WHERE A.JOB_ID IN (
<SUBQUERY>
AND A.ACCOUNT_ID IN (
<SUBQUERY>
AND FIELDNAME IN ( -- SHOULD BE INSIDE LEVEL1
<SUBQUERY>
) AD,
( SELECT ....
) FD
WHERE .... -
Retrieving query information from a SYS_REFCURSOR using XMLSEQUENCE
G'day.
I am trying to retrieve the colum name from the first column selected in a query. I have no idea what the column name is, however I was pointed in the direction of the following code snippet to help me retrieve the name:
DECLARE
v_rc_sv SYS_REFCURSOR;
v_query VARCHAR2(4000);
v_value_col_name VARCHAR2(4000) := NULL;
v_updated_query VARCHAR2(4000);
BEGIN
v_query := 'SELECT val FROM a_table';
OPEN v_rc_sv FOR v_query;
FOR gen_cursor IN (
SELECT ROWNUM rn,
t2.COLUMN_VALUE.getRootElement () NAME,
EXTRACTVALUE (t2.COLUMN_VALUE, 'node()') VALUE
FROM TABLE (XMLSEQUENCE (v_rc_sv)) t,
TABLE (XMLSEQUENCE (EXTRACT (COLUMN_VALUE, '/ROW/node()'))) t2)
LOOP
IF v_value_col_name IS NULL THEN
v_value_col_name := gen_cursor.NAME;
EXIT;
END IF;
END LOOP;
CLOSE v_rc_sv;
-- Now we have the column name, we can construct a query string which
-- wraps the original query with a standard select statement that includes the column
-- name.
v_updated_query := 'SELECT ' || v_value_col_name || ' FROM (' || v_query || ')';
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;From the last line, you can see I use the name of the column to wrap the query string, so that eventually I can use the updated query to retrieve the value from the query.
My question is, can I also use the same method (by using XMLSEQUENCE) to tell me how many columns have been selected in the unknown string ? Also can it tell me if the unknown query has put an alias on any of the select columns (and what they might be) or the query is using the original column name ? ie: select name from person_table VS select name the_name from person_table (where the_name is the column alias) ?
Edited by: Greg Block on May 27, 2010 5:59 PM
Apologies for the formatting, I had typed it nicely :)
Edited by: Greg Block on May 27, 2010 8:55 PM
Updated with the formatting tag, thanks for the tipHi,
If you're using 11g, you can take a look at UTL_XML.PARSEQUERY.
Here's an example with your requirement, it'll output the number of colums and their names (and aliases) :
DECLARE
tmplob clob;
parsed_qry xmltype;
num_of_cols number;
BEGIN
dbms_lob.createtemporary(tmplob, true);
utl_xml.parsequery(
user,
q'{SELECT employee_id as emp_id, last_name FROM hr.employees WHERE job_id = 'IT_PROG'}',
tmplob
--dbms_output.put_line(tmplob);
parsed_qry := xmltype(tmplob);
select count(*) into num_of_cols from xmltable('//SELECT_LIST_ITEM' passing parsed_qry);
dbms_output.put_line ('Number of column(s) : ' || to_char(num_of_cols));
for r in (
select *
from xmltable('//SELECT_LIST_ITEM'
passing parsed_qry
columns colnum for ordinality,
colname varchar2(30) path 'COLUMN_REF/COLUMN',
colalias varchar2(30) path 'COLUMN_ALIAS' default '<no alias>')
loop
dbms_output.put_line('Column '||to_char(r.colnum) || ' : ' || r.colname ||', alias = '||r.colalias);
end loop;
dbms_lob.freetemporary (tmplob);
END;
Apologies for the formatting, I had typed it nicelyI'm sure you did but the forum doesn't render it unless you enclose your code with tags. -
Extractvalue, extract, xmlsequence
Could someone explain what extractvalue, xmlsequence and extract is doing in the following query:
select
extractvalue(value(a),'Notebook/@Brand') As Brand
,extractvalue(value(a),'Notebook/@Model') As Model
from prod_xml_tab b,
table( xmlsequence( extract( demo_field,'Product/Notebook' ) ) ) a
where demo_field is not null;I went through documentation and still don't get it, and need some basic explanation step by step. for example, what is actually EXTRACT returning for first and second row?
the code for table and data is as follows:
create table prod_xml_tab (demo_field xmltype);
insert into prod_xml_tab values('
<Product type="Laptop">
<Notebook Brand="HP" Model="Pavilion dv6-3132TX Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>4 GB</RAM>
<Price>1189</Price>
<Display Type="LED" MonitorSize="15.6"/>
<Weight>4.14</Weight>
</Notebook>
<Notebook Brand="HP" Model="HP Pavilion dv6-3032TX Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>6 GB</RAM>
<Price>1104</Price>
<Display Type="LED" MonitorSize="15.6"/>
<Weight>4.1</Weight>
</Notebook>
<Notebook Brand="HP" Model="Pavilion dv6-3079TX Notebook">
<Harddisk>500 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>4 GB</RAM>
<Price>1099</Price>
<Display Type="LED" MonitorSize="15.6"/>
<Weight>4.14</Weight>
</Notebook>
</Product>');
insert into prod_xml_tab values('
<Product>
<Notebook Brand="Toshiba" Model="Satellite A660/07R 3D Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>4 GB</RAM>
<Price>1444</Price>
<Display Type="LED" MonitorSize="15.6"/>
<Weight>4.88</Weight>
</Notebook>
</Product>');943276 wrote:
thank you... this is a bit confusing when trying to reproduce excellent example on wrong version.
anyway, do you know what is this (+) doing formally? is this a notation similar to left outer join? I noticed it in some other example which I cannot find now.It is an outer join.
Example:
SQL> ed
Wrote file afiedt.buf
1 WITH xml_table AS
2 (SELECT xmltype('
3 <root>
4 <child name="name1">
5 <grandchild name="name11">
6 <greatgrandchild name="name111"/>
7 <greatgrandchild name="name112"/>
8 </grandchild>
9 <grandchild name="name12"/>
10 </child>
11 <child name="name2">
12 <grandchild name="name21">
13 <greatgrandchild name="name211"/>
14 </grandchild>
15 <grandchild name="name22"/>
16 </child>
17 </root>') object_value FROM dual)
18 select po.child_name, gc.gchild_name, ggc.ggchild_name
19 from xml_table p
20 ,xmltable('/root/child'
21 passing p.object_value
22 columns child_name varchar2(100) path '@name'
23 ,gchild xmltype path 'grandchild'
24 ) po
25 ,xmltable('/grandchild'
26 passing po.gchild
27 columns gchild_name varchar2(100) path '@name'
28 ,ggchild xmltype path 'greatgrandchild'
29 ) (+) gc
30 ,xmltable('/greatgrandchild'
31 passing gc.ggchild
32 columns ggchild_name varchar2(100) path '@name'
33* ) (+) ggc
SQL> /
CHILD_NAME GCHILD_NAME GGCHILD_NAME
name1 name11 name111
name1 name11 name112
name1 name12
name2 name21 name211
name2 name22without the outer joins it would just give...
SQL> ed
Wrote file afiedt.buf
1 WITH xml_table AS
2 (SELECT xmltype('
3 <root>
4 <child name="name1">
5 <grandchild name="name11">
6 <greatgrandchild name="name111"/>
7 <greatgrandchild name="name112"/>
8 </grandchild>
9 <grandchild name="name12"/>
10 </child>
11 <child name="name2">
12 <grandchild name="name21">
13 <greatgrandchild name="name211"/>
14 </grandchild>
15 <grandchild name="name22"/>
16 </child>
17 </root>') object_value FROM dual)
18 select po.child_name, gc.gchild_name, ggc.ggchild_name
19 from xml_table p
20 ,xmltable('/root/child'
21 passing p.object_value
22 columns child_name varchar2(100) path '@name'
23 ,gchild xmltype path 'grandchild'
24 ) po
25 ,xmltable('/grandchild'
26 passing po.gchild
27 columns gchild_name varchar2(100) path '@name'
28 ,ggchild xmltype path 'greatgrandchild'
29 ) gc
30 ,xmltable('/greatgrandchild'
31 passing gc.ggchild
32 columns ggchild_name varchar2(100) path '@name'
33* ) ggc
SQL> /
CHILD_NAME GCHILD_NAME GGCHILD_NAME
name1 name11 name111
name1 name11 name112
name2 name21 name211 -
Help with a simple XMLTable query
Newbie Oracle XML developer here and need a little guidance on how to retrieve multiple records in an xmltype table using xmltable.
My document in the xmltype table looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<echoems:ECHOMetrics xmlns:echoems="http://myURL/myFilename.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://myURL/myFilename.xsd
http://myURL/myFilename.xsd">
<OrderMetrics>
<OrderItemMetric>
<requestor>user1</requestor>
<product>123</product>
</OrderItemMetric>
<OrderItemMetric>
<requestor>0.0.0.0</requestor>
<product>ABC</product>
</OrderItemMetric>
<OrderItemMetric>
<requestor>user3</requestor>
<product>XYZ</product>
</OrderItemMetric>
</OrderMetrics>
</echoems:ECHOMetrics>
I want to get all the products:
Product
123
ABC
XYZ
I know to use XMLTable but am not sure how exactly to write it. If just one record, the following worked fine:
select extractvalue
(object_value,
'echoems:ECHOMetrics/OrderMetrics/OrderItemMetric/product',
'xmlns:echoems="http://myURL/myFilename.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
) object_value
from echoXML;
But with multiple records, I'm trying XMLTable but can't get it right. Trying something like this:
select m.product
from echoXML3
xmlTable(
(object_value,'echoems:ECHOMetrics/OrderMetrics/OrderItemMetric/*','xmlns:echoems="http://myURL/myFilename.xsd')
passing object_value
COLUMNS
product varchar2(85) path 'product') m;
Thanks in advance for any help on this.One more question. Instead of putting the xml doc in the query, how do I reference it from the xmlType table?
You have:
select *
from xmltable
'//OrderMetrics/OrderItemMetric'
passing xmltype(
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<echoems:ECHOMetrics xmlns:echoems="http://myURL/myFilename.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://myURL/myFilename.xsd">
<OrderMetrics>
<OrderItemMetric>
<requestor>user1</requestor>
<product>123</product>
</OrderItemMetric>
<OrderItemMetric>
<requestor>0.0.0.0</requestor>
<product>ABC</product>
</OrderItemMetric>
<OrderItemMetric>
<requestor>user3</requestor>
<product>XYZ</product>
</OrderItemMetric>
</OrderMetrics>
</echoems:ECHOMetrics>')
columns
prod varchar2(20) path 'product',
requestor varchar(50) path 'requestor'
However, the xmlDocument is already in an xmlType table called echoXML3 based on the xsd. I'm just trying to query it to get a relational result set. How, in the query above, do I replace the hardcoded xmlDoc with the xmlDoc located in my xmlType table?
I thought maybe something like this but it's not working:
select *
from xmltable
'//OrderMetrics/OrderItemMetric'
passing xmltype(select value(e)
from echoXML3,
TABLE(xmlsequence(extract(object_value,'echoems:ECHOMetrics/OrderMetrics/OrderItemMetric/*','xmlns:echoems="http://myURL/myFilename.xsd'))) e)
columns
prod varchar2(20) path 'product',
requestor varchar(50) path 'requestor'
Message was edited by:
user619814 -
Ora-03113 error with XMLTABLE inside subquery or view
I'm getting ORA-03113 error if I use a result of XMLTABLE inside a subquery of another query (whether XMLTABLE is inline, or from a view). Code below to reproduce this - vastly simplified and now rather meaningless - but produces same error. Has anyone saw this error re. XMLTABLE or know of metalink bugs on this ? I couldn't find anything. I'm having to use deprecated table(xmlsequence) instead, which doesn't get this error.
--DROP TABLE TEST
CREATE TABLE TEST(ID number(10), CUST_REF varchar2(50 char), XMLDATA XMLTYPE);
INSERT INTO TEST(ID, CUST_REF, XMLDATA) VALUES (1, 'XYZ',
XMLTYPE('<?xml version="1.0" encoding="utf-16"?>
<TESTXML
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:ABC-123:TESTXML">
<collections>
<TRANSACTION_COLLECTION>
<TRANSACTION>
<RECORD_ID>1</RECORD_ID>
<TRANSACTION_ID>7791786</TRANSACTION_ID>
<AMOUNT>335</AMOUNT>
<TYPE>I</TYPE>
<DC>DR</DC>
</TRANSACTION>
</TRANSACTION_COLLECTION>
</collections>
</TESTXML>'));
COMMIT;
CREATE VIEW TEST_XMLVIEW
AS
SELECT
ID,
CUST_REF,
xmltbl.RECORD_ID,
xmltbl.TRANSACTION_ID,
xmltbl.AMOUNT,
xmltbl.TYPE,
xmltbl.DC
FROM TEST,
XMLTable(XMLNamespaces(DEFAULT 'urn:ABC-123:TESTXML'),
'/TESTXML/collections/TRANSACTION_COLLECTION/TRANSACTION' PASSING TEST.XMLDATA
COLUMNS
"RECORD_ID" number(10) PATH 'RECORD_ID',
"TRANSACTION_ID" VARCHAR(200 CHAR) PATH 'TRANSACTION_ID',
"DC" VARCHAR(200 CHAR) PATH 'DC',
"TYPE" VARCHAR(200 CHAR) PATH 'TYPE',
"AMOUNT" NUMBER(38,8) PATH 'AMOUNT')
AS xmltbl;
WITH SUM_AMOUNTS (ID, CUST_REF, SUM_1, SUM_2, SUM_3)
AS
(SELECT ID, CUST_REF, SUM(AMOUNT) AS SUM_1, SUM(AMOUNT) AS SUM_2, SUM(AMOUNT) + SUM(AMOUNT) AS SUM_3
FROM TEST_XMLVIEW
GROUP BY ID, CUST_REF)
select
ID,
CUST_REF,
SUM_1,
SUM_2,
SUM_3
from SUM_AMOUNTS;
Version Details:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for 64-bit Windows: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - ProductionHas anyone saw this error re. XMLTABLE or know of metalink bugs on this ? I couldn't find anything.Really?
Go to the trace directory and find the relevant trace/incident file.
On my system, I can see something like this :
ORA-07445: exception encountered: core dump [evaopn3()+656] [ACCESS_VIOLATION] [ADDR:0x0] [PC:0x234A5B6] [UNABLE_TO_READ] []Copy/paste that line into the ORA-00600/ORA-07445 look-up tool on My Oracle Support and run the search for your version.
You will find this article :
*ORA-7445 (evaopn3) [ID 860969.1]*
and at the bottom of the page, among the known related bugs, this one :
*Bug 12724375 : ORA-7445 [evaopn3] from XQuery with GROUP BY* -
10g XMLTABLE - can I return XMLTYPE col as well as extract specific columns
Hi,
(This is for version 10.2.0.4)
Currently, we have a giant XML column which contains many parts to it. We split those into individual parts via XMLSEQUENCE and then loop through to extract information from two other XMLTYLE columns. I'd like to be able to use XMLTABLE to join the XMLTYPE columns to each other in one SQL statement, as I think it should be more efficient. (We're having issues when the big XML column has 400 or more parts in it - looping and doing extract values on two xmltype columns 400+ times is proving slow going!)
Anyway, what I'd like to do is use XMLTABLE to produce a table-like structure for each column, then join them so that 1st part in col1 = 1st part in col2 = 1st part in col3.
I've looked around at the documentation and google, but I'm getting stuck at one particular point - I would like to return both the XMLTYPE and specific extracted values from that XMLTYPE as part of the XMLTABLE on each column. I just can't seem to find a way to do it.
Here's an example (that I've nabbed from http://thinktibits.blogspot.com/2011/03/oracle-xmltable-example-part-1.html ) that will hopefully explain more clearly what I'd like to do, taking just one column to start with:
CREATE TABLE xml_test
(NOTEBOOK XMLTYPE);
insert into xml_test values ('<?xml version="1.0" encoding="UTF-8"?><Product Type=''Laptop''><Notebook Brand="HP" Model="Pavilion dv6-3132TX Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>4 GB</RAM></Notebook><Notebook Brand="HP" Model="HP Pavilion dv6-3032TX Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>6 GB</RAM></Notebook><Notebook Brand="Toshiba" Model="Satellite A660/07R 3D Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>4 GB</RAM></Notebook><Notebook Brand="Toshiba" Model="Satellite A660/15J Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i5</Processor><RAM>6 GB</RAM></Notebook></Product>');
commit;
SELECT NOTEBOOKS1.*
FROM xml_test PO,
XMLTable('//Notebook' PASSING PO.NOTEBOOK) notebooks1;
COLUMN_VALUE
<Notebook Brand="HP" Model="Pavilion dv6-3132TX Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>4 GB</RAM></Notebook>
<Notebook Brand="HP" Model="HP Pavilion dv6-3032TX Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>6 GB</RAM></Notebook>
<Notebook Brand="Toshiba" Model="Satellite A660/07R 3D Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i7</Processor><RAM>4 GB</RAM></Notebook>
<Notebook Brand="Toshiba" Model="Satellite A660/15J Notebook"><Harddisk>640 GB</Harddisk><Processor>Intel Core i5</Processor><RAM>6 GB</RAM></Notebook>
4 rows selected.
SELECT NOTEBOOKS2.*
FROM xml_test PO,
XMLTable('//Notebook' PASSING PO.NOTEBOOK
COLUMNS row_num for ordinality,
"BrandType" CHAR(10) PATH '@Brand',
"ProductModel" CHAR(50) PATH '@Model',
"Harddisk" CHAR(10) PATH 'Harddisk',
"Processor" CHAR(20) PATH 'Processor',
"RAM" CHAR(10) PATH 'RAM') AS NOTEBOOKS2;
ROW_NUM BrandType ProductModel Harddisk Processor RAM
1 HP Pavilion dv6-3132TX Notebook 640 GB Intel Core i7 4 GB
2 HP HP Pavilion dv6-3032TX Notebook 640 GB Intel Core i7 6 GB
3 Toshiba Satellite A660/07R 3D Notebook 640 GB Intel Core i7 4 GB
4 Toshiba Satellite A660/15J Notebook 640 GB Intel Core i5 6 GB
4 rows selected.What I'd like is to have the COLUMN_VALUE contents from the first select to appear as a column in the second select - is it possible?
At worst case, I could do a join, only that produces a cartesian product because I don't know how to label the rows from within the first query's XMLTABLE (if I used rownum in the query itself, does that guarentee to come out in the same order as the XMLTABLE results? Would part 1 always be labeled row 1, part 2 row2, etc?).
I hope that makes some sort of sense - I'm not up on XML terms, sadly.
ETA: If there's no way of doing this via XMLTABLE, is there any other way of achieving it?
Edited by: Boneist on 02-Dec-2011 17:14Hi,
Define an additional XMLType projection in the COLUMNS clause with PATH = '.' (the context item) :
SQL> set long 500
SQL>
SQL> SELECT x1.*
2 FROM xml_test t
3 , XMLTable('/Product/Notebook' PASSING t.notebook
4 COLUMNS rn FOR ORDINALITY
5 , BrandType VARCHAR2(10) PATH '@Brand'
6 , ProductModel VARCHAR2(50) PATH '@Model'
7 , Harddisk VARCHAR2(10) PATH 'Harddisk'
8 , Processor VARCHAR2(20) PATH 'Processor'
9 , RAM VARCHAR2(10) PATH 'RAM'
10 , NoteBook_node XMLType PATH '.'
11 ) x1
12 ;
RN BRANDTYPE PRODUCTMODEL HARDDISK PROCESSOR RAM NOTEBOOK_NODE
1 HP Pavilion dv6-3132TX Notebook 640 GB Intel Core i7 4 GB <Notebook Brand="HP" Model="Pavilion dv6-3132TX Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>4 GB</RAM>
</Notebook>
2 HP HP Pavilion dv6-3032TX Notebook 640 GB Intel Core i7 6 GB <Notebook Brand="HP" Model="HP Pavilion dv6-3032TX Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>6 GB</RAM>
</Notebook>
3 Toshiba Satellite A660/07R 3D Notebook 640 GB Intel Core i7 4 GB <Notebook Brand="Toshiba" Model="Satellite A660/07R 3D Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i7</Processor>
<RAM>4 GB</RAM>
</Notebook>
4 Toshiba Satellite A660/15J Notebook 640 GB Intel Core i5 6 GB <Notebook Brand="Toshiba" Model="Satellite A660/15J Notebook">
<Harddisk>640 GB</Harddisk>
<Processor>Intel Core i5</Processor>
<RAM>6 GB</RAM>
</Notebook>
I'm not sure I understand the rest of your requirement.
Do you want to further break the generated XMLType into a set of relational rows, or repeat the operation on different columns from the same base table?
Maybe you are looking for
-
I need help trying to format an external hard drive. My Mac won't recognise it anywhere other than System Profiler.
-
When I try to set up MS Outlook using Outlook Setup for Icloud it fails at step 2 of 7 Download Calender from iCloud with error message "your setup could not be started because of an unexpected error" My iCloud calender in Outlook had previously be
-
"Save AS' to Enterprie across firewall
Hi All, I am trying to save a report from Crystal Reports Designer into an Enterprise folder. The server is in a different network and I had to request the Network team to open up the port 6400 on the Crystal Server machine. But I am still getting "C
-
Adding a year to the current date field
Hello, Can any one please help on how to add a year to the current date field. e.g 7/19/2011 plus a year = 7/19/2012 Thanks, Han Dao
-
Office 2010 Displaying Duplicate Entries of the Same Printer
Hi, Looking for some guidance on how to resolve this odd behavior we're seeing in Office 2010. In each Office 2010 app, when you go to File > Print, we find that certain printer objects are duplicated. I'm able to repro this problem which has been