Xmltable information for meteo information
I have to obtain meteo information (es. weather) from this and store the values in a table ...
For example I would like to obatin the value "wx":"Light Rain"
http://www.classmeteo.it/REST-WS-Fluxes/resources/currentcond/currentByLocId/24040
Could someone help me with a query example?
Here is the http://www.classmeteo.it/REST-WS-Fluxes/resources/application.wadl
With google i did with this query ... but google is not yet available?
select *
from xmltable(
'/xml_api_reply/weather/current_conditions'
passing httpuritype('http://www.google.com/ig/api?weather=Cesano+Boscone').getXML()
columns condition varchar2(100) path 'icon/@data'
, temp_c number path 'temp_c/@data'
);
For example I would like to obatin the value "wx":"Light Rain"
http://www.classmeteo.it/REST-WS-Fluxes/resources/currentcond/currentByLocId/24040
Could someone help me with a query example?The method called returns a serialized JSON object. I doubt XMLTable is of any help in this situation.
If you're interested in a single value, try a regular expression.
Edit: well, you can do it with XMLTable without too much complexity provided the following is true :
- database release is 11.2
- JSON string is no more than 4000 bytes
- field value doesn't contain a comma
+(note that I didn't fully test the whole thing, as I couldn't get HttpUriType to work correctly)+
select trim('"' from field_name) as field_name
, trim('"' from field_value) as field_value
from xmltable(
'ora:tokenize(substring($json,2,string-length($json)-2), ",")'
passing dbms_lob.substr(
httpuritype('http://www.classmeteo.it/REST-WS-Fluxes/resources/currentcond/currentByLocId/24040').getclob()
) as "json"
columns field_name varchar2(30) path 'substring-before(.,":")'
, field_value varchar2(30) path 'substring-after(.,":")'
FIELD_NAME FIELD_VALUE
obsStn LIME
procTm 20130306062634
stnNm Bergamo
obsDayGmt 20130306
obsTmGmt 112000
dyNght D
locObsDay 20130306
locObsTm 121856
tmpF 46
tmpC 8
sky 11
wx Light Rain
iconExt 1201
alt 29.88
baroTrnd 0
baroTrndAsc Steady
ceilo 5000
ceilM 1524
clds BKN
dwptF 45
dwptC 7
hIF 46
hIC 8
rH 93
pres
presChnge
visM 4.97
visK 8.00
wCF 41
wCC 5
wDir 10
wDirAsc N
wGstM
wGstK
wGstKn
wSpdM 10
wSpdK 16
wSpdKn 9
tmpMx24F
tmpMx24C
tmpMn24F
tmpMn24C
tmpMx6F
tmpMx6C
tmpMn6F
tmpMn6C
prcp24
prcp3_6hr
prcpHr
prcpMTD
prcpYr
snwDep
snwIncr
snwTot
snwTot6hr
snwMTD
snwSsn
snwYr
sunrise 06:50 am
sunset 06:13 pm
uvIdx 2
uvDes Low
uvWrn 0
flsLkIdxF
flsLkIdxC
wtrTmpF
wtrTmpC
wvHghtF
wvHghtM
wvPrd
recTyp METAR
wndWvHghtF
wndWvHghtM
wndWvPrd
swllHghtF
swllHghtM
swllPrd
swllDir
hrdCd
vocalCd
80 rows selected
Edited by: odie_63 on 6 mars 2013 13:14
Similar Messages
-
How to pass parameter into extract function (for XMLTYPE)
I have a table PROBLEMXML with XMLTYPE field xml_column. In this column there are several deffinitions for the problem. There is no max amount of deffinitions and it can be no definition at all. I need to return all definitions for every problem as a string wirh definitions separated by ";".
Query
SELECT extract(prob.Def,'/Definitions/Definition[1]/@var') || ';'|| extract(prob.Def,'/Definitions/Definition[2]/@var')
FROM PROBLEMXML j ,
XMLTABLE (
'/problem'
PASSING j.xml_column
COLUMNS probid VARCHAR (31) PATH '/problem/@id',
Def XMLTYPE PATH '/problem/Definitions') prob
where PROBLEM_ID =1;
returns exactly what I want a;m.
But
declare
my_var varchar2(2000) :=null;
n1 number;
n2 number;
begin
n1:=1;
n2:=2;
SELECT extract(prob.Def,'/Definitions/Definition[n1]/@var') || '|'|| extract(prob.Def,'/Definitions/Definition[n2]/@var') into my_var
FROM ETL_PROBLEMXML_STG_T j ,
XMLTABLE (
'/problem'
PASSING j.xml_column
COLUMNS probid VARCHAR (31) PATH '/problem/@id',
Def XMLTYPE PATH '/problem/Definitions') prob
where PROBLEM_ID =1;
dbms_output.put_line(my_var);
end;
returns NULL.
Is there is a way to pass parameter into extract function?I need to return all definitions for every problem as a string wirh definitions separated by ";".In XQuery, there's the handy function "string-join" for that.
For example :
SQL> WITH etl_problemxml_stg_t AS (
2 SELECT 1 problem_id,
3 xmltype('<problem id="1">
4 <Definitions>
5 <Definition var="var1"></Definition>
6 <Definition var="var2"></Definition>
7 <Definition var="var3"></Definition>
8 </Definitions>
9 </problem>') xml_column
10 FROM dual
11 )
12 SELECT j.problem_id,
13 prob.probid,
14 prob.def
15 FROM etl_problemxml_stg_t j,
16 XMLTable(
17 'for $i in /problem
18 return element r
19 {
20 $i/@id,
21 element d { string-join($i/Definitions/Definition/@var, ";") }
22 }'
23 passing j.xml_column
24 columns
25 probid varchar2(30) path '@id',
26 def varchar2(100) path 'd'
27 ) prob
28 ;
PROBLEM_ID PROBID DEF
1 1 var1;var2;var3 -
create table emp (doc XMLtype);
insert into emp values(
xmltype('<dept bldg="114">
<employee id="903">
<name>
<first>Mary</first>
<last>Jones</last>
</name>
<office>415</office>
<phone>905-403-6112</phone>
<phone>647-504-4546</phone>
<salary currency="USD">64000</salary>
</employee>
</dept>'));
I need the output to be
Mary Jones 905-403-6112,647-504-4546
I tried
SELECT X.* FROM emp ,
XMLTABLE ('$d/dept/employee' passing doc as "d"
COLUMNS
first VARCHAR2(25) PATH 'name/first',
last VARCHAR2(25) PATH 'name/last',
phone VARCHAR2(100) PATH 'fn:string-join(phone/text(),",")'
) AS X
and received error
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00601: Invalid token in: '/*/fn:string-join(phone/text(),",")'
please advise. thanks.SCOTT@soti_10> with emp as(
2 select xmltype(
3 '
4 <dept>
5 <employee id="901">
6 <name>
7 <first>John</first>
8 <last>Doe</last>
9 </name>
10 </employee>
11 <employee id="902">
12 <name>
13 <first>Peter</first>
14 <last>Pan</last>
15 </name>
16 <phone>905-416-5004</phone>
17 </employee>
18 <employee id="903">
19 <name>
20 <first>Mary</first>
21 <last>Jones</last>
22 </name>
23 <phone>905-403-6112</phone>
24 <phone>647-504-4546</phone>
25 </employee>
26 </dept>
27 '
28 ) as doc
29 from dual
30 )
31 SELECT X.*
32 FROM emp ,
33 XMLTABLE (
34 'for $e in $d/dept/employee,
35 (: $pi - index of the current phone element.
36 If there is no phone elements at all then $pi = 0, otherwise $pi > 0 :)
37 $pi in (0 to fn:count($e/phone))[. > 0 or fn:last() = 1]
38 return <e>
39 {$e/name}
40 {$e/phone[$pi]}
41 </e>'
42 passing doc as "d"
43 COLUMNS first VARCHAR2(25) PATH 'name/first',
44 last VARCHAR2(25) PATH 'name/last',
45 phone VARCHAR2(100) PATH 'phone'
46 ) AS X
47 ;
FIRST LAST PHONE
John Doe
Peter Pan 905-416-5004
Mary Jones 905-403-6112
Mary Jones 647-504-4546Regards,
Dima -
I seem to be getting strange or at least unexpected results from the result of a PL SQL Query that uses XMLTable() in Oracle 11g1.
I have a table in Oracle that looks like this -
CREATE TABLE EPBNI_XML_TEST
(<blockquote>RRN VARCHAR(24) PRIMARY KEY,
ClipID VARCHAR2(27),
Lodgement XMLType</blockquote>)
XMLTYPE COLUMN Lodgement
STORE AS OBJECT RELATIONAL
ELEMENT "ConditionReportCreateRequest_1.xsd#ConditionReportCreateRequest_1";
Each XML Document stored in the XMLTYPE Column Lodgement is a little bit like this (simplified) -
<ConditionReportCreateRequest_1>
<blockquote>
<Content><blockquote><X-Report><blockquote><Report-Header><blockquote><RRN>123</RRN>
<Report-Type>type A</Report-Type>
<Status>status A</Status></blockquote></Report-Header></blockquote></X-Report></blockquote></blockquote><blockquote><blockquote><Y-Report></blockquote></blockquote><blockquote><blockquote><blockquote><Report-Header></blockquote></blockquote></blockquote><blockquote><blockquote><blockquote><blockquote><RRN>321</RRN>
<Report-Type>type B</Report-Type>
<Status>status B</Status></blockquote></Report-Header></blockquote></Y-Report></blockquote></Content></blockquote></ConditionReportCreateRequest_1>
Each Lodgement can have one or more reports in the XML document. What I am trying to acheive is getting a single list of the RRN, Report-Type and Status of every report, e.g.
RRN Report-Type Status
123 type A status A
321 type B status B
112 type A status A
113 type C status A
etc... etc....
My PL SQL and XQuery looks a bit like this -
SELECT xtab.RRN, xtab.ReportType, xtab.ReportStatus from
EPBNI_XML_TEST,
XMLTable('<blockquote>for $reportHeader in /ConditionReportCreateRequest_1/Content/child::element()/Report-Header return
<report>
$reportHeader/RRN,
$reportHeader/Report-Type,
$reportHeader/Status
</report></blockquote>'
PASSING LODGEMENT
COLUMNS
RRN VARCHAR2(24) PATH 'RRN',
ReportType VARCHAR2(1) PATH 'Report-Type',
ReportStatus VARCHAR2(10) PATH 'Status'
) xtab;
The problem is though that I seem to get only 1 result for each row of the table. I.e. if I have 9,000 rows in the EPBNI_XML_TEST table I only get 9,000 results. However I need one result for each report in each lodgement, probably closer to 18,000 results. Also all 9,000 results are the same - which I dont understand - i.e. all 9,000 are -
RRN Report-Type Status
123 type A status A
123 type A status A
123 type A status A
(upto 9000 identical result rows...)
What am I doing wrong or mis-understanding here?
Thanks Adam.
Edited by: adamretter on Oct 29, 2008 2:39 PMtry this
SELECT xtab.RRN, xtab.ReportType, xtab.ReportStatus from
EPBNI_XML_TEST,
,xmltable('/ConditionReportCreateRequest_1/Content/*/Report-Header'
passing LODGEMENT
columns
rrn varchar2(24) path 'RRN/text()'
,reporttype varchar2(10) path 'Report-Type/text()'
,status varchar2(10) path 'Status/text()') xtab;**not tested** -
XMLTABLE / XQUERY performance
Hi all,
Below is a sample XML representing a spreadsheet :
<Table>
<Row>
<Cell><Data>1</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell><Data>B</Data></Cell>
<Cell Index="5"><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>2</Data></Cell>
<Cell Index="3"><Data>B</Data></Cell>
<Cell><Data>C</Data></Cell>
</Row>
<Row>
<Cell><Data>3</Data></Cell>
<Cell Index="3"><Data>B</Data></Cell>
<Cell Index="5"><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>4</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell><Data>B</Data></Cell>
<Cell><Data>C</Data></Cell>
<Cell><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>5</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell Index="4"><Data>C</Data></Cell>
<Cell><Data>D</Data></Cell>
</Row>
</Table>which should be interpreted as :
cols --> 1 2 3 4 5
1 A B D
2 B C
3 B D
4 A B C D
5 A C DAs you can see, for each row, empty cells are simply omitted in the document.
The next non-empty cell is then marked with an Index attribute representing its true position on the row.
My requirement is to query the document and access the values based on cells positions on the row.
Because of empty cells, Data values cannot be accessed by a simple xpath like "/Cell[n]/Data".
So I came up with the following :
WITH t AS (
select xmltype(
'<Table>
<Row>
<Cell><Data>1</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell><Data>B</Data></Cell>
<Cell Index="5"><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>2</Data></Cell>
<Cell Index="3"><Data>B</Data></Cell>
<Cell><Data>C</Data></Cell>
</Row>
<Row>
<Cell><Data>3</Data></Cell>
<Cell Index="3"><Data>B</Data></Cell>
<Cell Index="5"><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>4</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell><Data>B</Data></Cell>
<Cell><Data>C</Data></Cell>
<Cell><Data>D</Data></Cell>
</Row>
<Row>
<Cell><Data>5</Data></Cell>
<Cell><Data>A</Data></Cell>
<Cell Index="4"><Data>C</Data></Cell>
<Cell><Data>D</Data></Cell>
</Row>
</Table>') doc from dual
SELECT x.*
FROM t, xmltable(
'for $j in /Table/Row
return <ROW> {
for $i at $pos in $j/Cell
let $x := $j/Cell[position()<=$pos and @Index][last()]/@Index
let $x2 := if($x) then $x else 1
let $p := count($j/Cell[@Index=$x]/preceding-sibling::*)+1
return <DATA pos="{$pos - $p + $x2}">{$i/Data/text()}</DATA>
} </ROW>'
PASSING t.doc
COLUMNS cell1 number PATH '/ROW/DATA[@pos="1"]',
cell2 varchar2(1) PATH '/ROW/DATA[@pos="2"]',
cell3 varchar2(1) PATH '/ROW/DATA[@pos="3"]',
cell4 varchar2(1) PATH '/ROW/DATA[@pos="4"]',
cell5 varchar2(1) PATH '/ROW/DATA[@pos="5"]'
) x;Basically, the XQUERY reconstructs each row and gives each cell its true position. We can then access the data with a simple position predicate.
It works well for small documents, but rapidly shows awful performance as the size increases (which is understandable).
So my question : is there a better way to achieve the requirement (or to improve performance)?
Thanks a lot.
(DB version is 10.2.0.4)
Edited by: odie_63 on 28 déc. 2009 19:21what if you do the logic outside of the xquery?
like this:
SQL> set timi on;
SQL> WITH t AS (
2 select xmltype(
3 '<Table>
4 <Row>
5 <Cell><Data>1</Data></Cell>
6 <Cell><Data>A</Data></Cell>
7 <Cell><Data>B</Data></Cell>
8 <Cell Index="5"><Data>D</Data></Cell>
9 </Row>
10 <Row>
11 <Cell><Data>2</Data></Cell>
12 <Cell Index="3"><Data>B</Data></Cell>
13 <Cell><Data>C</Data></Cell>
14 </Row>
15 <Row>
16 <Cell><Data>3</Data></Cell>
17 <Cell Index="3"><Data>B</Data></Cell>
18 <Cell Index="5"><Data>D</Data></Cell>
19 </Row>
20 <Row>
21 <Cell><Data>4</Data></Cell>
22 <Cell><Data>A</Data></Cell>
23 <Cell><Data>B</Data></Cell>
24 <Cell><Data>C</Data></Cell>
25 <Cell><Data>D</Data></Cell>
26 </Row>
27 <Row>
28 <Cell><Data>5</Data></Cell>
29 <Cell><Data>A</Data></Cell>
30 <Cell Index="4"><Data>C</Data></Cell>
31 <Cell><Data>D</Data></Cell>
32 </Row>
33 </Table>') doc from dual
34 )
35 SELECT x.*
36 FROM t, xmltable(
37 'for $j in /Table/Row
38 return <ROW> {
39 for $i at $pos in $j/Cell
40 let $x := $j/Cell[position()<=$pos and @Index][last()]/@Index
41 let $x2 := if($x) then $x else 1
42 let $p := count($j/Cell[@Index=$x]/preceding-sibling::*)+1
43 return <DATA pos="{$pos - $p + $x2}">{$i/Data/text()}</DATA>
44 } </ROW>'
45 PASSING t.doc
46 COLUMNS cell1 number PATH '/ROW/DATA[@pos="1"]',
47 cell2 varchar2(1) PATH '/ROW/DATA[@pos="2"]',
48 cell3 varchar2(1) PATH '/ROW/DATA[@pos="3"]',
49 cell4 varchar2(1) PATH '/ROW/DATA[@pos="4"]',
50 cell5 varchar2(1) PATH '/ROW/DATA[@pos="5"]'
51 ) x;
CELL1 C C C C
1 A B D
2 B C
3 B D
4 A B C D
5 A C D
Elapsed: 00:00:00.64
SQL>
SQL> WITH t AS (
2 select xmltype('<Table>
3 <Row>
4 <Cell><Data>1</Data></Cell>
5 <Cell><Data>A</Data></Cell>
6 <Cell><Data>B</Data></Cell>
7 <Cell Index="5"><Data>D</Data></Cell>
8 </Row>
9 <Row>
10 <Cell><Data>2</Data></Cell>
11 <Cell Index="3"><Data>B</Data></Cell>
12 <Cell><Data>C</Data></Cell>
13 </Row>
14 <Row>
15 <Cell><Data>3</Data></Cell>
16 <Cell Index="3"><Data>B</Data></Cell>
17 <Cell Index="5"><Data>D</Data></Cell>
18 </Row>
19 <Row>
20 <Cell><Data>4</Data></Cell>
21 <Cell><Data>A</Data></Cell>
22 <Cell><Data>B</Data></Cell>
23 <Cell><Data>C</Data></Cell>
24 <Cell><Data>D</Data></Cell>
25 </Row>
26 <Row>
27 <Cell><Data>5</Data></Cell>
28 <Cell><Data>A</Data></Cell>
29 <Cell Index="4"><Data>C</Data></Cell>
30 <Cell><Data>D</Data></Cell>
31 </Row>
32 </Table>') doc from dual)
33 select
34 case when v.cell_1_index is null then v.cell_1 end cell_one
35 , case when nvl(v.cell_1_index,-1)=2 then v.cell_1
36 when v.cell_2_index is null and v.cell_1_index is null then v.cell_2
37 end cell_two
38 , case when nvl(v.cell_1_index,-1)=3 then v.cell_1
39 when nvl(v.cell_2_index,-1)=3 then v.cell_2
40 when v.cell_1_index=2 and v.cell_2_index is null then v.cell_2
41 when coalesce(v.cell_1_index,v.cell_2_index,v.cell_3_index) is null then v.cell_3
42 end cell_three
43 , case when nvl(v.cell_1_index,-1)=4 then v.cell_1
44 when nvl(v.cell_2_index,-1)=4 then v.cell_2
45 when nvl(v.cell_3_index,-1)=4 then v.cell_3
46 when v.cell_1_index=2 and v.cell_2 is not null and v.cell_3_index is null then v.cell_3
47 when v.cell_1_index=3 and v.cell_2 is not null and v.cell_4_index is null then v.cell_2
48 when v.cell_2_index=3 and v.cell_3_index is null then v.cell_3
49 when coalesce(v.cell_1_index,v.cell_2_index,v.cell_3_index,v.cell_4_index) is null then v.cell_4
50 end cell_four
51 , case when nvl(v.cell_1_index,-1)=5 then v.cell_1
52 when nvl(v.cell_2_index,-1)=5 then v.cell_2
53 when nvl(v.cell_3_index,-1)=5 then v.cell_3
54 when nvl(v.cell_4_index,-1)=5 then v.cell_4
55 when v.cell_1_index=3 and v.cell_2_index is null then v.cell_3
56 when v.cell_1_index=4 then v.cell_2
57 when v.cell_3_index=4 then v.cell_4
58 when v.cell_2_index=3 and v.cell_3_index is null and v.cell_4_index is null then v.cell_4
59 when coalesce(v.cell_1_index,v.cell_2_index,v.cell_3_index,v.cell_4_index) is null then v.cell_5
60 end cell_five
61 from
62 t,xmltable('/Table/Row'
63 passing t.doc
64 columns
65 cell_1 varchar2(10) path 'Cell[1]/Data'
66 ,cell_1_index number path 'Cell[1]/@Index'
67 ,cell_2 varchar2(10) path 'Cell[2]/Data'
68 ,cell_2_index number path 'Cell[2]/@Index'
69 ,cell_3 varchar2(10) path 'Cell[3]/Data'
70 ,cell_3_index number path 'Cell[3]/@Index'
71 ,cell_4 varchar2(10) path 'Cell[4]/Data'
72 ,cell_4_index number path 'Cell[4]/@Index'
73 ,cell_5 varchar2(10) path 'Cell[5]/Data'
74 ) v;
CELL_ONE CELL_TWO CELL_THREE CELL_FOUR CELL_FIVE
1 A B D
2 B C
3 B D
4 A B C D
5 A C D
Elapsed: 00:00:00.04
SQL> spool off;Edited by: Ants Hindpere on Mar 10, 2010 1:03 AM -
ExtractValue vs. XMLTable Character Entity Decoding
In removing the deprecated extract/extractValue methods from my queries, I have run into an issue with character data being extracted via XMLTable.
Character entity encoded data (e.g. "'" as "'") was decoded by extractValue, but remains encoded by XMLTable. For example:
WITH myXML AS
SELECT XMLTYPE.createXML('<root desc="Here' || chr(38) || 'apos;s an example"/>') AS x
FROM dual
SELECT
x,
extractValue(x, '/root/@desc'),
mytab.example,
XMLQuery('/root/@desc' PASSING x RETURNING CONTENT).getStringVal()
FROM
myXML,
XMLTable
'/root'
PASSING myXML.x
COLUMNS
example VARCHAR2(39) PATH '@desc'
) mytab;returns
<root desc="Here's an example"/> Here's an example Here's an example Here's an example
Wrapping each column in the SELECT clause in dbms_xmlgen.convert() seems like overkill. Am I doing something wrong?
Thanks.Funny, didn't notice that one before.
It seems it happens only with attributes in transient XMLType instances.
For example, it works if the XML document is store in an XMLType column/table :
SQL> create table tmp_xml of xmltype;
Table created
SQL> set scan off
SQL> insert into tmp_xml values (xmltype('<root desc="Here's an example">R&D</root>'));
1 row inserted
SQL>
SQL> SELECT x.*
2 FROM tmp_xml t
3 , XMLTable('/root'
4 PASSING t.object_value
5 COLUMNS
6 example varchar2(20) PATH '@desc'
7 , content varchar2(30) PATH 'text()'
8 ) x
9 ;
EXAMPLE CONTENT
Here's an example R&D
Workaround with a transient XMLType : the fn:data() function
SQL> SELECT x.*
2 FROM XMLTable('/root'
3 PASSING xmltype('<root desc="Here's an example">R&D</root>')
4 COLUMNS
5 example varchar2(20) PATH '@desc'
6 , content varchar2(30) PATH 'text()'
7 ) x
8 ;
EXAMPLE CONTENT
Here's an examp R&D
SQL>
SQL> SELECT x.*
2 FROM XMLTable('/root'
3 PASSING xmltype('<root desc="Here's an example">R&D</root>')
4 COLUMNS
5 example varchar2(20) PATH 'data(@desc)'
6 , content varchar2(30) PATH 'text()'
7 ) x
8 ;
EXAMPLE CONTENT
Here's an example R&D -
What is going on with the syntax of XMLTABLE?
Hello! What is that with the syntax XMLTABLE? For example
from tgc_xml tt2, xmltable('/ROWSET/ROW' passing tt2.xml_field) tgc;
That is first I have to declare the table in front of the function call, then, after a comma, call a function with that table. How do I write such functions? If I can't do that in PL/SQL, how did Oracle did it?
[Oracle documentation|http://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb_xquery.htm#CBAHBFGE]
Oracle documentation says:
Whenever a PASSING clause refers to a column of an XMLType table in a query, that table must appear before the XMLTable expression in the query FROM list. This is because the XMLTable expression depends on the XMLType table — a left lateral (correlated) join is needed, to ensure a one-to-many (1:N) relationship between the XMLType table row accessed and the rows generated from it by XMLTable.Hi,
That is first I have to declare the table in front of the function call, then, after a comma, call a function with that table. How do I write such functions? If I can't do that in PL/SQL, how did Oracle did it?What's so confusing about it? It's a built-in function based on the SQL/XML standards, just like XMLElement, XMLAgg etc.
Conceptually, we can see XMLTable as a pipelined table function, with a syntax of its own.
Something like this, for instance, is not that much different, and it's available to us in (PL/)SQL :
SELECT x.*
FROM my_table t
, TABLE(
my_pipefunction(t.col1, t.col2)
) x
; -
G'day all,
Running the following set-up: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
Getting a full table scan on a table with an FBI.
Here is a sample set-up:
create table a (id number, filepath varchar2(256 char));
insert into a values(1,'/dir/subdir/file1.xml');
insert into a values(2,'/dir/subdir/file2.xml');
insert into a values(3,'/dir/subdir/file3.xml');
insert into a values(4,'/dir/subdir/file4.xml');
insert into a values(5,'/dir/subdir/file5.xml');
commit;
create index filepath_substr_fbi on a(substr(filepath,instr(filepath,'/',-1)+1));
create unique index filepath_uidx on a(filepath);So the requirement is to retrieve the ids from the table containing a particular filename. The filenames to retrieve are sourced from an xmltype. The approach I've taken is the following:
select * from a , (XMLTable('for $j in /task/related_files/ora:tokenize(text(),"\|")
where ora:matches($j,"\d+\.xml") return normalize-space($j)'
PASSING xmltype(
'<task><related_files>File 1|file1.xml|file 2|file2.xml|file 3|file3.xml</related_files></task>'
))) x where substr(a.filepath,instr(a.filepath,'/',-1)+1) = x.column_value.getstringval();which returns the following results:
"ID" "FILEPATH" "COLUMN_VALUE"
1 "/dir/subdir/file1.xml" file1.xml
2 "/dir/subdir/file2.xml" file2.xml
3 "/dir/subdir/file3.xml" file3.xmlNow, after running this sample, and doing an explain plan on it, I did notice it used the index!
Execution Plan
Plan hash value: 107833345
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 408 | 109K| 32 (4)| 00:00:01 |
| 1 | MERGE JOIN | | 408 | 109K| 32 (4)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID | A | 5 | 1365 | 2 (0)| 00:00:01 |
| 3 | INDEX FULL SCAN | FILEPATH_SUBSTR_FBI | 5 | | 1 (0)| 00:00:01 |
|* 4 | SORT JOIN | | 408 | 816 | 30 (4)| 00:00:01 |
|* 5 | COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE | 408 | 816 | 29 (0)| 00:00:0
Predicate Information (identified by operation id):
4 - access(SUBSTR("FILEPATH",INSTR("FILEPATH",'/',(-1))+1)="XMLTYPE"."GETSTRINGVAL"(XMLCDATA(SYS_
QNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1)))
filter(SUBSTR("FILEPATH",INSTR("FILEPATH",'/',(-1))+1)="XMLTYPE"."GETSTRINGVAL"(XMLCDATA(SYS_
QNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1)))
5 - filter( REGEXP_LIKE (SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0),'\d+\.xml'))
Note
- dynamic sampling used for this statement (level=2)Now for some reason, my actual code (which is not much different than sample above)..gets the following plan:
Execution Plan
Plan hash value: 1696443977
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 449 | 53431 | 33 (4)| 00:00:01 |
|* 1 | HASH JOIN | | 449 | 53431 | 33 (4)| 00:00:01 |
| 2 | TABLE ACCESS FULL | DATA_CAPTURE_RECORD | 11 | 1287 | 3 (0)| 00:00:01 |
|* 3 | COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE | 408 | 816 | 29 (0)| 00:00
Predicate Information (identified by operation id):
1 - access(SUBSTR("DRAFT_VPATH",INSTR("DRAFT_VPATH",'/',(-1))+1)="XMLTYPE"."GETSTRINGVAL"(XMLCDAT
A(SYS_XQNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1)))
3 - filter( REGEXP_LIKE (SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0),'\d+\.xml'))Here is the sql query for the above plan:
select * from data_capture_record x, (XMLTable('for $j in /task/related_tasks/ora:tokenize(text(),"\|")
where ora:matches($j,"\d+\.xml") return normalize-space($j)'
PASSING xmltype(
'<task><related_tasks>Actioning a Reminder Work Item or a BFd Action Item Work Item for Jury Service - clean up this Edit - another Edit | 17.xml| ROE Correct WI Received for a Regular ROE s | 24.xml| Sending benefit statement copies that are currently archived . | 10.xml| Test of TINY MCE Configurations - Test Edit. | 46.xml|</related_tasks> </task>'
))) a where substr(x.DRAFT_VPATH,instr(x.DRAFT_VPATH,'/',-1)+1) = a.column_value.getstringval();Any ideas? A quick note, i just started getting into xquery this week..so if you spot something, or see a better solution to my problem, please let me know...
Thanks for any help or advice.
StephaneIndeed, cardinality and selectivity are essential in this case.
Consider the following test case with a 1,000,000-row table, the CBO picks up the index :
Connected to:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - Production
SQL> create table test2 as
2 select level as path_id
3 , cast('/dir/subdir/file'||to_char(level,'fm0999999')||'.xml' as varchar2(256)) as filepath
4 from dual
5 connect by level <= 1000000 ;
Table created.
SQL> select count(*) from test2;
COUNT(*)
1000000
SQL> create index test2_ix on test2 ( substr(filepath, instr(filepath, '/', -1) + 1) );
Index created.
SQL> exec dbms_stats.gather_table_stats(user, 'TEST2');
PL/SQL procedure successfully completed.
SQL> set lines 120
SQL> set autotrace on explain
SQL> select *
2 from test2 t
3 where substr(filepath, instr(filepath, '/', -1) + 1) in (
4 select filename
5 from xmltable(
6 'for $i in ora:tokenize(/task/related_files, "\|")
7 where ora:matches($i, "\d+\.xml")
8 return normalize-space($i)'
9 passing xmlparse(document '<task><related_files>File 1| file0000001.xml|file 2|file0999999.xml |file 3|file0007773.xml</related_files></
task>')
10 columns filename varchar2(30) path '.'
11 ) x
12 ) ;
PATH_ID FILEPATH
1 /dir/subdir/file0000001.xml
7773 /dir/subdir/file0007773.xml
999999 /dir/subdir/file0999999.xml
Execution Plan
Plan hash value: 420041503
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 257 | 13107 | 643 (1)| 00:00:08 |
| 1 | NESTED LOOPS | | 257 | 13107 | 643 (1)| 00:00:08 |
| 2 | SORT UNIQUE | | 408 | 816 | 29 (0)| 00:00:01 |
|* 3 | COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE | 408 | 816 | 29 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | TEST2 | 1 | 49 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | TEST2_IX | 1 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
3 - filter( REGEXP_LIKE (SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0),'\d+\.xml'))
5 - access(SUBSTR("FILEPATH",INSTR("FILEPATH",'/',-1)+1)=CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_XQ
_PKSQL2XML(SYS_XQNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1,2,0),0,0,20971520,0),50,1,2) AS
varchar2(30) ))
Note
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)
SQL> select t.*
2 from test2 t
3 join xmltable(
4 'for $i in ora:tokenize(/task/related_files, "\|")
5 where ora:matches($i, "\d+\.xml")
6 return normalize-space($i)'
7 passing xmlparse(document '<task><related_files>File 1| file0000001.xml|file 2|file0999999.xml |file 3|file0007773.xml</related_files></ta
sk>')
8 columns filename varchar2(30) path '.'
9 ) x
10 on substr(t.filepath, instr(t.filepath, '/', -1) + 1) = x.filename
11 ;
PATH_ID FILEPATH
1 /dir/subdir/file0000001.xml
999999 /dir/subdir/file0999999.xml
7773 /dir/subdir/file0007773.xml
Execution Plan
Plan hash value: 1810535419
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 411 | 20961 | 1254 (1)| 00:00:16 |
| 1 | NESTED LOOPS | | 411 | 20961 | 1254 (1)| 00:00:16 |
|* 2 | COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE | 408 | 816 | 29 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID | TEST2 | 1 | 49 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TEST2_IX | 1 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter( REGEXP_LIKE (SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0),'\d+\.xml'))
4 - access(SUBSTR("FILEPATH",INSTR("FILEPATH",'/',-1)+1)=CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_X
Q_PKSQL2XML(SYS_XQNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1,2,0),0,0,20971520,0),50,1,2)
AS varchar2(30) ))
Note
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information)From the plans above we see that the CBO estimates 408 rows from XMLTable.
This estimation could be refined by using hints : CARDINALITY (not documented), DYNAMIC_SAMPLING, or by using a wrapper function and the extensible optimizer feature.
For example, if you expect at most 10 rows every time :
SQL> select /*+ cardinality(x 10) */ t.*
2 from test2 t
3 join xmltable(
4 'for $i in ora:tokenize(/task/related_files, "\|")
5 where ora:matches($i, "\d+\.xml")
6 return normalize-space($i)'
7 passing xmlparse(document '<task><related_files>File 1| file0000001.xml|file 2|file0999999.xml |file 3|file0007773.xml</related_files></ta
sk>')
8 columns filename varchar2(30) path '.'
9 ) x
10 on substr(t.filepath, instr(t.filepath, '/', -1) + 1) = x.filename
11 ;
PATH_ID FILEPATH
1 /dir/subdir/file0000001.xml
999999 /dir/subdir/file0999999.xml
7773 /dir/subdir/file0007773.xml
Execution Plan
Plan hash value: 1810535419
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 10 | 510 | 59 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 10 | 510 | 59 (0)| 00:00:01 |
|* 2 | COLLECTION ITERATOR PICKLER FETCH| XQSEQUENCEFROMXMLTYPE | 10 | 20 | 29 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID | TEST2 | 1 | 49 | 3 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TEST2_IX | 1 | | 2 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter( REGEXP_LIKE (SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0),'\d+\.xml'))
4 - access(SUBSTR("FILEPATH",INSTR("FILEPATH",'/',-1)+1)=CAST(SYS_XQ_UPKXML2SQL(SYS_XQEXVAL(SYS_X
Q_PKSQL2XML(SYS_XQNORMSPACE(SYS_XQ_UPKXML2SQL(VALUE(KOKBF$),2,1,0)),1,2,0),0,0,20971520,0),50,1,2)
AS varchar2(30) ))
Note
- Unoptimized XML construct detected (enable XMLOptimizationCheck for more information) -
11g release 2 Unable to Select updatedXML
Version: Oracle 11g Rel 2
XML stored AS BASICFILE BINARY XML
Updated XML using AppendChildXML, however unable to Query the Element/Attribute.Appreciate any help.
<SearchRecord>
<RECORD>
<ObjectInfo>
<Terms>
<FlexTerm FlexTermName="AuthKeyword">
<FlexTermValue>Possibility theory</FlexTermValue>
</FlexTerm>
<FlexTerm FlexTermName="AuthKeyword2">
<FlexTermValue>Possibility theory2</FlexTermValue>
</FlexTerm>
*<ClassTerm>*
*<ClassCode TermVocab="BulkTesting"/>*
*</ClassTerm>*
</Terms>
</ObjectInfo>
</RECORD>
</SearchRecord>
Try the following....
INSERT INTO TESTXML(CSXML_GOID,CSXML_DOC,CSXML_DATASET)VALUES(
1241,
XMLTYPE(' <SearchRecord>
<RECORD>
<ObjectInfo>
<Terms>
<FlexTerm FlexTermName="AuthKeyword">
<FlexTermValue>Possibility theory</FlexTermValue>
</FlexTerm>
<FlexTerm FlexTermName="AuthKeyword2">
<FlexTermValue>Possibility theory2</FlexTermValue>
</FlexTerm>
<ClassTerm>
<ClassCode TermVocab="BulkTesting"/>
</ClassTerm>
</Terms>
</ObjectInfo>
</RECORD>
</SearchRecord>'));
SELECT
XML.TermVocab
FROM
testxml csxml,
XMLTABLE(
'for $i in SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm/ClassCode
return element e {$i/@TermVocab }'
PASSING CSXML.CSXML_DOC COLUMNS TermVocab VARCHAR2(2000) PATH '@TermVocab' )
XML
where csxml_goid =1241;
---works result :BulkTesting
----Delete node:
UPDATE testxml -- Delete Node
SET csxml_doc =
DELETEXML(CSXML_DOC, '/SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm')
WHERE CSXML_GOID = 1241;
--appendchildxml
UPDATE testxml SET csxml_doc=
APPENDCHILDXML(CSXML_DOC,
'/SearchRecord/RECORD/ObjectInfo/Terms',
XMLTYPE('<ClassTerm>
<ClassCode TermVocab="BulkTesting"/>
</ClassTerm>'))
WHERE CSXML_GOID = 1241;
SELECT
XML.Author
FROM
testxml csxml,
XMLTABLE(
'for $i in SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm/ClassCode
return element e {$i/@TermVocab }'
PASSING CSXML.CSXML_DOC COLUMNS AUTHOR VARCHAR2(2000) PATH '@TermVocab' )
XML
where csxml_goid =1241;
--now rows
Appreciate any help.
Thansk,
SubuHi,
I tried to reproduce on this sample :
Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
Connected as dev
SQL> CREATE TABLE test_xml (
2 id number,
3 doc xmltype
4 )
5 XMLTYPE doc STORE AS BASICFILE BINARY XML;
Table created
SQL> INSERT INTO test_xml values(1,
2 xmltype('<SearchRecord>
3 <RECORD>
4 <ObjectInfo>
5 <Terms>
6 <FlexTerm FlexTermName="AuthKeyword">
7 <FlexTermValue>Possibility theory</FlexTermValue>
8 </FlexTerm>
9 <FlexTerm FlexTermName="AuthKeyword2">
10 <FlexTermValue>Possibility theory2</FlexTermValue>
11 </FlexTerm>
12 <ClassTerm>
13 <ClassCode TermVocab="BulkTesting"/>
14 </ClassTerm>
15 </Terms>
16 </ObjectInfo>
17 </RECORD>
18 </SearchRecord>')
19 );
1 row inserted
SQL> UPDATE test_xml
2 SET doc = DELETEXML(doc, '/SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm')
3 WHERE id = 1;
1 row updated
SQL> UPDATE test_xml
2 SET doc = APPENDCHILDXML(doc,
3 '/SearchRecord/RECORD/ObjectInfo/Terms',
4 XMLTYPE('<ClassTerm>
5 <ClassCode TermVocab="BulkTesting"/>
6 </ClassTerm>'))
7 WHERE id = 1;
1 row updated
SQL> SELECT xml.TermVocab
2 FROM test_xml t,
3 XMLTABLE(
4 'for $i in /SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm/ClassCode
5 return element e {$i/@TermVocab }'
6 PASSING t.DOC COLUMNS TermVocab VARCHAR2(2000) PATH '@TermVocab'
7 ) xml
8 WHERE id = 1;
TERMVOCAB
SQL>And here's the execution plan, a streaming XPath evaluation occurs (as expected with binary xml storage) :
Plan hash value: 779000122
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 8168 | 15M| 32 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 8168 | 15M| 32 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| TEST_XML | 1 | 2015 | 3 (0)| 00:00:01 |
| 3 | XPATH EVALUATION | | | | | |
Predicate Information (identified by operation id):
2 - filter("ID"=1)
Note
- dynamic sampling used for this statement (level=2)See below the result by suppressing the XPath evaluation :
SQL> SELECT /*+ NO_XML_QUERY_REWRITE */
2 xml.TermVocab
3 FROM test_xml t,
4 XMLTABLE(
5 'for $i in /SearchRecord/RECORD/ObjectInfo/Terms/ClassTerm/ClassCode
6 return element e {$i/@TermVocab }'
7 PASSING t.DOC COLUMNS TermVocab VARCHAR2(2000) PATH '@TermVocab'
8 ) xml
9 WHERE id = 1;
TERMVOCAB
BulkTesting
It works.
So it seems that the XPath scan over the content is causing the problem.
However, when serialized, the content appears OK :
SQL> SELECT x.doc.getclobval() FROM test_xml x;
X.DOC.GETCLOBVAL()
<SearchRecord>
<RECORD>
<ObjectInfo>
<Terms>
<FlexTerm FlexTermName="AuthKeyword">
<FlexTermValue>Possibility theory</FlexTermValue>
</FlexTerm>
<FlexTerm FlexTermName="AuthKeyword2">
<FlexTermValue>Possibility theory2</FlexTermValue>
</FlexTerm>
<ClassTerm>
<ClassCode TermVocab="BulkTesting"/>
</ClassTerm>
</Terms>
</ObjectInfo>
</RECORD>
</SearchRecord>
But this is definitely strange :
SQL> SELECT x.*
2 FROM test_xml t,
3 XMLTABLE(
4 'for $i in /SearchRecord/RECORD/ObjectInfo/Terms/FlexTerm
5 return $i'
6 PASSING t.doc COLUMNS flexterm xmltype path '.' ) x
7 WHERE id = 1;
FLEXTERM
<FlexTerm FlexTermName="AuthKeyword">
<FlexTermValue>Possibility theory</FlexTermValue>
</FlexTerm>
<FlexTerm FlexTermName="AuthKeyword2">
<FlexTermValue>Possibility theory2</FlexTermValue>
</FlexTerm>
<FlexTerm>
<ClassCode TermVocab="BulkTesting"/>
</FlexTerm>
SQL> -
Problem with xs:integer (I think)
Hi,
Firstly, I'm using Oracle database version 11.2.0.1.0
The overall task is to absorb data from an XML file and create records in a single destination table.
I've studied the excellent thread at Load xml data in Oracle table
and copied and hacked Odie's examples.
I've got something to work, but there's just that one final problem, explained so.
To test out my code, I wrapped the "select" that gets the data from the XML file into a cursor For loop, and inside
the loop body I just use dbms_output so I can see that the values are being processed okay. This works a treat, so my
final task was to abandon the cursor For loop and instead make the select statement the source of data for an Insert
statement. This is where my plans become unstuck.
In order to cater for duplicate rows, I'm using the "at" bit of the "for" loop as so: "for $i at $bibnum in /collection/record".
That bit of data (available through the variable "$bibnum") when printed out via the older dbms_output code did show
a pleasing consecutive sequence of digits. But try and insert this into a plain database table and all I get is nulls. Yuk.
Trying to read around this, I've managed through dubious means to glean that the variable is of type "xs:integer". It seems converting
this to a oracle "number" type is problematic. There is mention on the web page http://docs.oracle.com/cd/E14571_01/doc.1111/e15867/app_xquery_sql_reference.htm
about conversion from "number" to "xs:integer", hence I am presuming that the converse also holds.
But the blooming thing still doesn't work.
Other numbers from the select statement populate into my destination table fine. It's just the xs:integer that's the issue.
I've tried changing the "columns" part of the xmltable call and used "number", "number(8)", "number(8,0)" and other variants. No joy.
I've also tried changing the column type of the target table. Still no joy.
I've tried converting the xs:integer to a xs:decimal, and then use that. Still nothing.
Time to throw myself on the mercy of the forum. Any easy way to convert the xs:integer into a plain string?
If there is no obvious answer, I will throw together a small self-contained piece of example code and come back here.
Any help appreciated; thanks in advance.
Mungo (newbie with xmltables - probably going round the "long" way on this task :-)That's a funny one, SELECT is working but INSERT is not...
I guess it's an issue with the CBO and XQuery optimization.
If you're always using a variable as your XML source, you can disable it by adding the NO_XML_QUERY_REWRITE hint. It should solve the problem :
SQL> create table raw_bib (
2 recordID number
3 , datafieldID number
4 , tag number
5 , subfield varchar2(10)
6 , val varchar2(4000)
7 )
8 ;
Table created
SQL> var xml_data varchar2(4000)
SQL>
SQL> begin
2 :xml_data := '<collection>
3 <record>
4 <datafield tag="1">
5 <subfield code="1d1s1">ABC</subfield>
6 <subfield code="1d1s2">DEF</subfield>
7 <subfield code="1d1s3">GHI</subfield>
8 </datafield>
9 <datafield tag="2">
10 <subfield code="1d2s1">ABC</subfield>
11 <subfield code="1d2s2">DEF</subfield>
12 <subfield code="1d2s3">GHI</subfield>
13 </datafield>
14 </record>
15 <record>
16 <datafield tag="1">
17 <subfield code="2d1s1">ABC</subfield>
18 <subfield code="2d1s2">DEF</subfield>
19 <subfield code="2d1s3">GHI</subfield>
20 </datafield>
21 </record>
22 </collection>';
23 end;
24 /
PL/SQL procedure successfully completed
SQL>
SQL> insert into raw_bib(recordID, datafieldID, tag, subfield, val)
2 select /*+ no_xml_query_rewrite */
3 recordID, datafieldID, tag, subfield, val
4 from xmltable(
5 'for $i at $bibnum in /collection/record
6 return
7 for $j at $dfnum in $i/datafield
8 return
9 for $k in $j/subfield
10 return element r {
11 element finalData {data($k)}
12 , element datafieldtag {data($j/@tag) }
13 , element subfieldcode { data($k/@code) }
14 , element whichdatafield {data($dfnum)}
15 , element bibnumber { $bibnum }
16 }
17 '
18 passing xmltype(:xml_data)
19 columns recordID number path 'bibnumber'
20 , datafieldID number path 'whichdatafield'
21 , tag number path 'datafieldtag'
22 , subfield varchar2(10) path 'subfieldcode'
23 , val varchar2(4000) path 'finalData'
24 )
25 ;
9 rows inserted
SQL> select * from raw_bib;
RECORDID DATAFIELDID TAG SUBFIELD VAL
1 1 1 1d1s1 ABC
1 1 1 1d1s2 DEF
1 1 1 1d1s3 GHI
1 2 2 1d2s1 ABC
1 2 2 1d2s2 DEF
1 2 2 1d2s3 GHI
2 1 1 2d1s1 ABC
2 1 1 2d1s2 DEF
2 1 1 2d1s3 GHI
9 rows selected -
How to insert data in the table without join and using mapped rule value
1.Table SOL_K
A B C D – Columns Name
C D A B –Coulmns Values Defined (Rule --- Defined)
2.SECOND table SIC_K
SIC_ K
A B C D
Kamal Micky NULL MANOJ
3 Table SIC_Mapping
Same Columns A B C D based On Table SOL_K defined rule
I want to insert values(from table SIC K) into table SICMapping Table with the help of first table(SOL_K)(mapped rule)
Required Result SIC_Mapping Table
The output will be come like this.
A B C D — Columns Name
NULL MANOJ Kamal Micky ---- Came based on defined Mapping RuleWhat's your database version?
That's a funny requirement.
How about :
select case sol.a
when 'A' then sic.a
when 'B' then sic.b
when 'C' then sic.c
when 'D' then sic.d
end as a
, case sol.b
when 'A' then sic.a
when 'B' then sic.b
when 'C' then sic.c
when 'D' then sic.d
end as b
, case sol.c
when 'A' then sic.a
when 'B' then sic.b
when 'C' then sic.c
when 'D' then sic.d
end as c
, case sol.d
when 'A' then sic.a
when 'B' then sic.b
when 'C' then sic.c
when 'D' then sic.d
end as d
from sol_k sol, sic_k sic
;XQuery can do the trick too :
SQL> SELECT *
2 FROM XMLTable(
3 'for $i in ora:view("SIC_K")/ROW
4 return element r {
5 for $j in ora:view("SOL_K")/ROW/child::*
6 return element {name($j)} {$i/child::*[name()=$j]/text()}
7 }'
8 columns
9 a varchar2(30) path 'A'
10 , b varchar2(30) path 'B'
11 , c varchar2(30) path 'C'
12 , d varchar2(30) path 'D'
13 );
A B C D
MANOJ Kamal Micky
Edited by: odie_63 on 29 juin 2011 22:07 -
Loading data into XMLType column using dbms_xmlsave.insertxml get ORA-29532
The following simple test case succeeded in 9.2.0.1 but failed in 9.2.0.2.
CREATE OR REPLACE procedure InsertXML(xmlDoc IN VARCHAR2, tableName IN VARCHAR2) is
insCtx DBMS_XMLSave.ctxType;
rows number;
begin
insCtx := DBMS_XMLSave.newContext(tableName); -- get the context handle
rows := DBMS_XMLSave.insertXML(insCtx,xmlDoc); -- this inserts the document
dbms_output.put_line(to_char(rows) || ' rows inserted');
DBMS_XMLSave.closeContext(insCtx); -- this closes the handle
end;
CREATE TABLE XMLtable
(column1 xmltype)
exec insertxml('<?xml version = "1.0"?><ROWSET><ROW><COLUMN1><TEST>HELLO</TEST></COLUMN1></ROW></ROWSET>', 'XMLTABLE');Hi,
For your XML file I think you just need to enclose XML elemnts in ROWSET AND ROW TAGS - so xml should look like :
<ROWSET>
<ROW>
<DEPT>
</DEPT>
and just pass it as CLOB to dbms_xmlsave.insertXML proc.
I hope it should work.
I am also trying to insert XML file but with a bit complex structure having multiple nested elements.
I am not sure how to transform the external XML file to wrap it in ROWSET/ROW using XSLT. It's mandatory to use ROWSET/ROW tags to be able to insert in oracle tables. I am facing this problem right now. I am using object views to accomplish the purpose but still needs to figure out the way to apply stylesheet to incoming XML file.
If you come to know of any way, pls do let me know also.
Thanks -
Read XML file into databased using stored procedure
I need to read an xml file into my database using a stored procedure. I looked at a couple of tutorials, but I am kind of lost and am looking for some guidance. I will eventually need to only pull a handfull of the data in based on the USER ID. Any help will be greatly appreciated. I have been given a schema file and an example file of how the data will me sent to me. The schema file is below:
<h1>Schema File</h1>
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by Turbo XML 2.4.1.100. Conforms to w3c http://www.w3.org/2001/XMLSchema-->
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xsd:element name="root">
<xsd:complexType />
</xsd:element>
<xsd:element name="Report">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="Biller" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Biller">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="BillerName" />
<xsd:element ref="BillerIdNumber" />
<xsd:element ref="PartnerInfo" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="BillerName">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="BillerIdNumber">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="PartnerInfo">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="PartnerName" />
<xsd:element ref="PartnerVenderNumber" />
<xsd:element ref="PartnerStreet01" />
<xsd:element ref="PartnerStreet02" />
<xsd:element ref="PartnerCity" />
<xsd:element ref="PartnerState" />
<xsd:element ref="PartnerZip" />
<xsd:element ref="PartnerCountry" />
<xsd:element ref="PartnerActive" />
<xsd:element ref="PartnerContactName" />
<xsd:element ref="PartnerEmailAddress" />
<xsd:element ref="PartnerContactPhone" />
<xsd:element ref="PartnerFaxNumber" />
<xsd:element ref="PartnerUpdateUser" />
<xsd:element ref="PartnerUpdateDate" />
<xsd:element ref="PartnerDocColor" />
<xsd:element ref="PartnerDocDistribution" />
<xsd:element ref="PartnerDocPrinting" />
<xsd:element ref="PartnerDocTiming" />
<xsd:element ref="Delivery" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PartnerName">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="PartnerVenderNumber">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="PartnerStreet01">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerStreet02">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerCity">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerState">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerZip">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerCountry">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerActive">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerContactName">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerEmailAddress">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerContactPhone">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerFaxNumber">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerUpdateUser">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerUpdateDate">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerDocColor">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerDocDistribution">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerDocPrinting">
<xsd:complexType />
</xsd:element>
<xsd:element name="PartnerDocTiming">
<xsd:complexType />
</xsd:element>
<xsd:element name="Delivery">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="DeliveryType" />
<xsd:element ref="DeliveryContactName" />
<xsd:choice>
<xsd:element ref="ReceivingStreet01" />
<xsd:element ref="ReceivingStreet02" />
<xsd:element ref="ReceivingCity" />
<xsd:element ref="ReceivingState" />
<xsd:element ref="ReceivingZip" />
<xsd:element ref="ReceivingCountry" />
<xsd:element ref="DeliveryEmailAddress" />
<xsd:element ref="DeliveryCompanyId" />
<xsd:element ref="DeliveryUserId" />
<xsd:element ref="DeliveryFormatType" />
<xsd:element ref="SecureType" />
<xsd:element ref="SecureQuestion" />
<xsd:element ref="SecureAnswer" />
<xsd:element ref="DeliveryFaxNumber" />
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryType">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryContactName">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryEmailAddress">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="SecureType">
<xsd:complexType />
</xsd:element>
<xsd:element name="SecureQuestion">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="SecureAnswer">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryFormatType">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryCompanyId">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryUserId">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="DeliveryFaxNumber">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="ReceivingStreet01">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="ReceivingStreet02">
<xsd:complexType />
</xsd:element>
<xsd:element name="ReceivingCity">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="ReceivingState">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="ReceivingZip">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
<xsd:element name="ReceivingCountry">
<xsd:complexType mixed="true">
<xsd:choice />
</xsd:complexType>
</xsd:element>
</xsd:schema>
<h1>Example File</h1>
<?xml version="1.0" encoding="utf-8"?>
<Report>
<Biller>
<BillerName>DONATO TEST BILLER</BillerName>
<BillerIdNumber>999999999</BillerIdNumber>
<PartnerInfo>
<PartnerName>TEST TRADING PARTNER</PartnerName>
<PartnerVenderNumber>999999999</PartnerVenderNumber>
<PartnerStreet01 />
<PartnerStreet02 />
<PartnerCity />
<PartnerState />
<PartnerZip />
<PartnerCountry />
<PartnerActive />
<PartnerContactName />
<PartnerEmailAddress />
<PartnerContactPhone />
<PartnerFaxNumber />
<PartnerUpdateUser />
<PartnerUpdateDate />
<PartnerDocColor />
<PartnerDocDistribution />
<PartnerDocPrinting />
<PartnerDocTiming />
<Delivery>
<DeliveryType>EMAIL</DeliveryType>
<DeliveryContactName>Kiran</DeliveryContactName>
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
</Delivery>
<Delivery>
<DeliveryType>SECURE</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<SecureType />
<SecureQuestion>Pet Name</SecureQuestion>
<SecureAnswer>040698de9bf14ef87d8cbaf46b8ecddc</SecureAnswer>
<DeliveryFormatType />
</Delivery>
<Delivery>
<DeliveryType>CEO</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<DeliveryCompanyId>WFADM618</DeliveryCompanyId>
<DeliveryUserId>PAULSEN</DeliveryUserId>
<DeliveryFormatType />
</Delivery>
<Delivery>
<DeliveryType>FAX</DeliveryType>
<DeliveryContactName>Kiran</DeliveryContactName>
<DeliveryFaxNumber>4807244340</DeliveryFaxNumber>
<DeliveryFormatType>PDF</DeliveryFormatType>
</Delivery>
<Delivery>
<DeliveryType>DOC</DeliveryType>
<DeliveryContactName />
<ReceivingStreet01>2600 South Price Road</ReceivingStreet01>
<ReceivingStreet02 />
<ReceivingCity>Chandler</ReceivingCity>
<ReceivingState>AZ</ReceivingState>
<ReceivingZip>85248</ReceivingZip>
<ReceivingCountry>United States</ReceivingCountry>
</Delivery>
<Delivery>
<DeliveryType>DR</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<DeliveryCompanyId>WFADM618</DeliveryCompanyId>
<DeliveryUserId>PAULSEN</DeliveryUserId>
<DeliveryFormatType />
</Delivery>
</PartnerInfo>
</Biller>
</Report>Try with a XMLTABLE function
For example to Extract BillerName and BillerID
with t as(select xmltype( '<?xml version="1.0" encoding="utf-8"?>
<Report>
<Biller>
<BillerName>DONATO TEST BILLER</BillerName>
<BillerIdNumber>999999999</BillerIdNumber>
<PartnerInfo>
<PartnerName>TEST TRADING PARTNER</PartnerName>
<PartnerVenderNumber>999999999</PartnerVenderNumber>
<PartnerStreet01 />
<PartnerStreet02 />
<PartnerCity />
<PartnerState />
<PartnerZip />
<PartnerCountry />
<PartnerActive />
<PartnerContactName />
<PartnerEmailAddress />
<PartnerContactPhone />
<PartnerFaxNumber />
<PartnerUpdateUser />
<PartnerUpdateDate />
<PartnerDocColor />
<PartnerDocDistribution />
<PartnerDocPrinting />
<PartnerDocTiming />
<Delivery>
<DeliveryType>EMAIL</DeliveryType>
<DeliveryContactName>Kiran</DeliveryContactName>
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
</Delivery>
<Delivery>
<DeliveryType>SECURE</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<SecureType />
<SecureQuestion>Pet Name</SecureQuestion>
<SecureAnswer>040698de9bf14ef87d8cbaf46b8ecddc</SecureAnswer>
<DeliveryFormatType />
</Delivery>
<Delivery>
<DeliveryType>CEO</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<DeliveryCompanyId>WFADM618</DeliveryCompanyId>
<DeliveryUserId>PAULSEN</DeliveryUserId>
<DeliveryFormatType />
</Delivery>
<Delivery>
<DeliveryType>FAX</DeliveryType>
<DeliveryContactName>Kiran</DeliveryContactName>
<DeliveryFaxNumber>4807244340</DeliveryFaxNumber>
<DeliveryFormatType>PDF</DeliveryFormatType>
</Delivery>
<Delivery>
<DeliveryType>DOC</DeliveryType>
<DeliveryContactName />
<ReceivingStreet01>2600 South Price Road</ReceivingStreet01>
<ReceivingStreet02 />
<ReceivingCity>Chandler</ReceivingCity>
<ReceivingState>AZ</ReceivingState>
<ReceivingZip>85248</ReceivingZip>
<ReceivingCountry>United States</ReceivingCountry>
</Delivery>
<Delivery>
<DeliveryType>DR</DeliveryType>
<DeliveryContactName />
<DeliveryEmailAddress>[email protected]</DeliveryEmailAddress>
<DeliveryCompanyId>WFADM618</DeliveryCompanyId>
<DeliveryUserId>PAULSEN</DeliveryUserId>
<DeliveryFormatType />
</Delivery>
</PartnerInfo>
</Biller>
</Report>')xml from dual)
select q.* from t,xmltable('/Report' passing t.xml columns
BillerName varchar2(20) PATH
'/Report//Biller/BillerName')q
BILLERNAME BILLERID
DONATO TEST BILLER 999999999 -
Parsing a string in a given order
Hi All,
I want to parse a string and rank it in a given order.
Eg : i have a string as 'A | B | C | D'. I would like to parse this string and give a rank in order.
It should appear as below.
Parsed string order
D 1
C 2
B 3
A 4
Any help is greatly appreciated..A database version would help us providing you with a relevant solution.
Starting with 10g, you can do :
SQL> var my_str varchar2(30)
SQL> exec :my_str := 'A|B|C|D'
PL/SQL procedure successfully completed
SQL> select item
2 , row_number() over(order by item desc) as rank
3 from (
4 select regexp_substr(:my_str,'[^|]+',1,level) as item
5 from dual
6 connect by level <= length(regexp_replace(:my_str,'[^|]+')) + 1
7 );
ITEM RANK
D 1
C 2
B 3
A 4
In 11.2 :
SQL> select *
2 from xmltable(
3 'for $i in ora:tokenize($str,"\|") order by $i descending return $i'
4 passing 'A|B|C|D' as "str"
5 columns item varchar2(10) path '.'
6 , rank for ordinality
7 )
8 ;
ITEM RANK
D 1
C 2
B 3
A 4
Edited by: odie_63 on 11 janv. 2012 12:56 - added 11.2 -
I have posted the following thread in the SQL/PLSQL forum and would appreciate your input as it is realted to XML.
Re: Importing/Parsing XML using SQL and/or PL/SQL
Thanks in advance for your help
David
Message was edited by:
David FergusonHi David, please do visit the XML DB forum. There is an Oracle guy named Mark Drake and he is very good at this stuff. To your questions, yes, Oracle XML DB can handle any type of XML no matter how many levels you have. Check out the XMLTable function in the Oracle XML user's guide and it is pretty powerful. The trick is that it is hard if not impossible to combine singletons and multiples, because multiples require its own handling. I have to deal with this a lot. In some cases, I can use two xmltables, one for the multiples and one for the singlton, repeating the singleton for each of the multiples in one table. In other cases I just do two steps: get the multiples and singltons separately. You will find that using the global temporary table for this type of xml processing comes handy. At our place, some people use BizTalk to "map, orchestrate, factor and re-factor" xml messages from a partner, but I use Oracle XML DB. I have completed all available xml messages (more than 20) in just a short time, but it took the BizTalk consultants almost 5 months to finish one simple xml message! When I say Oracle does a beautiful job, they are not happy so they tell me that I should have been an Oracle salesman.
Ben
Maybe you are looking for
-
Do I need a convertor/transformer?
I am moving from the UK to the USA in a few weeks and note that the voltages in the two countries are different. I bought my MacBook in the UK but I have an apple two pin plug to connect my MacBook to a wall socket in the US. Do I also need some sort
-
Wish I could have phrased the question better, but here's what I need to know: I traded an older iPad for a Mac Mini. I made the trade with my daughter who, after transferring everything to her iMac, handed me over the Mac Mini with all her files, an
-
Help on iphone and ipod touch sync
i have an ipod touch, and i just rescently purchased a iphone 4s. I want to use the same apple id for both, but i don't want all the apps and music i have now on my ipod touch. if i plug in my iphone on the same comp and itunes will it sync all the a
-
HP Printer update 2.7 causes inky disaster with Photosmart B9180
Just a heads up that installing the HP printer update 2.7 through software update creates a huge problem with the Photosmart B9180. After routinely installing this update last month, I finally decided to print something. It came out of the printer al
-
What is "apple-scc-20120126-112417"?
I just discovered this in my Login Items. It's "Kind" is "Unknown," and when I right-click on "Reveal in Finder," nothing happens. Besides the obvious date reference (20120126), I haven't a clue what it's all about.