Inserting XML file into a Table
Hello,
Can someone provide me with a sample code to load xml files into a table. Thanks a lot.
Rajeesh
Keeping my fingers crossed that this quote from "Building XML Oracle Applications" by Steve Muench (O'Reilly & Associates, 2000, ISBN 1-56592-691-9) falls into the "fair use" category, and that you want it in PL/SQL, here is a procedure:
PROCEDURE insertXMLFile
(dir VARCHAR2, file VARCHAR2, name VARCHAR2 := NULL) IS
theBFile BFILE;
theCLob CLOB;
theDocName VARCHAR2(200) := NVL(name,file);
BEGIN
-- (1) Insert a new row into xml_documents with an empty CLOB, and
-- (2) Retrieve the empty CLOB into a variable with RETURNING.INTO
INSERT INTO stylesheets(docname,sheet) VALUES(theDocName,empty_clob( ))
RETURNING sheet INTO theCLob;
-- (3) Get a BFile handle to the external file
theBFile := BFileName(dir,file);
-- (4) Open the file
dbms_lob.fileOpen(theBFile);
-- (5) Copy the contents of the BFile into the empty CLOB
dbms_lob.loadFromFile(dest_lob => theCLob, src_lob => theBFile, amount => dbms_lob.getLength(theBFile));
-- (6) Close the file and commit
dbms_lob.fileClose(theBFile);
COMMIT;
END;
Similar Messages
-
How to load a XML file into a table
Hi,
I've been working on Oracle for many years but for the first time I was asked to load a XML file into a table.
As an example, I've found this on the web, but it doesn't work
Can someone tell me why? I hoped this example could help me.
the file acct.xml is this:
<?xml version="1.0"?>
<ACCOUNT_HEADER_ACK>
<HEADER>
<STATUS_CODE>100</STATUS_CODE>
<STATUS_REMARKS>check</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>2</SEGMENT_NUMBER>
<REMARKS>rp polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>3</SEGMENT_NUMBER>
<REMARKS>rp polytechnic administration</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>4</SEGMENT_NUMBER>
<REMARKS>rp polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>5</SEGMENT_NUMBER>
<REMARKS>rp polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
<HEADER>
<STATUS_CODE>500</STATUS_CODE>
<STATUS_REMARKS>process exception</STATUS_REMARKS>
</HEADER>
<DETAILS>
<DETAIL>
<SEGMENT_NUMBER>20</SEGMENT_NUMBER>
<REMARKS> base polytechnic</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>30</SEGMENT_NUMBER>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>40</SEGMENT_NUMBER>
<REMARKS> base polytechnic finance</REMARKS>
</DETAIL>
<DETAIL>
<SEGMENT_NUMBER>50</SEGMENT_NUMBER>
<REMARKS> base polytechnic logistics</REMARKS>
</DETAIL>
</DETAILS>
</ACCOUNT_HEADER_ACK>
For the two tags HEADER and DETAILS I have the table:
create table xxrp_acct_details(
status_code number,
status_remarks varchar2(100),
segment_number number,
remarks varchar2(100)
before I've created a
create directory test_dir as 'c:\esterno'; -- where I have my acct.xml
and after, can you give me a script for loading data by using XMLTABLE?
I've tried this but it doesn't work:
DECLARE
acct_doc xmltype := xmltype( bfilename('TEST_DIR','acct.xml'), nls_charset_id('AL32UTF8') );
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS[$hn]/DETAIL'
passing acct_doc as "d",
x1.header_no as "hn"
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
END;
This should allow me to get something like this:
select * from xxrp_acct_details;
Statuscode status remarks segement remarks
100 check 2 rp polytechnic
100 check 3 rp polytechnic administration
100 check 4 rp polytechnic finance
100 check 5 rp polytechnic logistics
500 process exception 20 base polytechnic
500 process exception 30
500 process exception 40 base polytechnic finance
500 process exception 50 base polytechnic logistics
but I get:
Error report:
ORA-06550: line 19, column 11:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got NUMBER
ORA-06550: line 4, column 2:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
and if I try to change the script without using the column HEADER_NO to keep track of the header rank inside the document:
DECLARE
acct_doc xmltype := xmltype( bfilename('TEST_DIR','acct.xml'), nls_charset_id('AL32UTF8') );
BEGIN
insert into xxrp_acct_details (status_code, status_remarks, segment_number, remarks)
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'/ACCOUNT_HEADER_ACK/DETAILS'
passing acct_doc
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
END;
I get this message:
Error report:
ORA-19114: error during parsing the XQuery expression:
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 4
19114. 00000 - "error during parsing the XQuery expression: %s"
*Cause: An error occurred during the parsing of the XQuery expression.
*Action: Check the detailed error message for the possible causes.
My oracle version is 10gR2 Express Edition
I do need a script for loading xml files into a table as soon as possible, Give me please a simple example for understanding and that works on 10gR2 Express Edition
Thanks in advance!The reason your first SQL statement
select x1.status_code,
x1.status_remarks,
x2.segment_number,
x2.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS[$hn]/DETAIL'
passing acct_doc as "d",
x1.header_no as "hn"
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS'
) x2
returns the error you noticed
PL/SQL: ORA-00932: inconsistent datatypes: expected - got NUMBER
is because Oracle is expecting XML to be passed in. At the moment I forget if it requires a certain format or not, but it is simply expecting the value to be wrapped in simple XML.
Your query actually runs as is on 11.1 as Oracle changed how that functionality worked when 11.1 was released. Your query runs slowly, but it does run.
As you are dealing with groups, is there any way the input XML can be modified to be like
<ACCOUNT_HEADER_ACK>
<ACCOUNT_GROUP>
<HEADER>....</HEADER>
<DETAILS>....</DETAILS>
</ACCOUNT_GROUP>
<ACCOUNT_GROUP>
<HEADER>....</HEADER>
<DETAILS>....</DETAILS>
</ACCOUNT_GROUP>
</ACCOUNT_HEADER_ACK>
so that it is easier to associate a HEADER/DETAILS combination? If so, it would make parsing the XML much easier.
Assuming the answer is no, here is one hack to accomplish your goal
select x1.status_code,
x1.status_remarks,
x3.segment_number,
x3.remarks
from xmltable(
'/ACCOUNT_HEADER_ACK/HEADER'
passing acct_doc
columns header_no for ordinality,
status_code number path 'STATUS_CODE',
status_remarks varchar2(100) path 'STATUS_REMARKS'
) x1,
xmltable(
'$d/ACCOUNT_HEADER_ACK/DETAILS'
passing acct_doc as "d",
columns detail_no for ordinality,
detail_xml xmltype path 'DETAIL'
) x2,
xmltable(
'DETAIL'
passing x2.detail_xml
columns segment_number number path 'SEGMENT_NUMBER',
remarks varchar2(100) path 'REMARKS') x3
WHERE x1.header_no = x2.detail_no;
This follows the approach you started with. Table x1 creates a row for each HEADER node and table x2 creates a row for each DETAILS node. It assumes there is always a one and only one association between the two. I use table x3, which is joined to x2, to parse the many DETAIL nodes. The WHERE clause then joins each header row to the corresponding details row and produces the eight rows you are seeking.
There is another approach that I know of, and that would be using XQuery within the XMLTable. It should require using only one XMLTable but I would have to spend some time coming up with that solution and I can't recall whether restrictions exist in 10gR2 Express Edition compared to what can run in 10.2 Enterprise Edition for XQuery. -
Loading XML file into DB Table
Hi
I m quite new to the loading XML file into database table.
It will be great if anyone could guide me to through.
Now,
i have an XML file which has to be loaded into the DB table.
what are the steps involved in doing this. How do i go from here ??
your help is greatly appriciated ???
Thank you so much!!
-ShashiOK - Although you really should read the XMLDB FAQ on this forum, here is some sample code of ONE of the ways of doing it
(there are multiple ways - and this is not the most simple one)
Based on Oracle 11gR1
-- sqlplus /nolog
clear screen
set termout on
set feed on
set lines 40
set long 10000000
set serveroutput on
set lines 100
set echo on
connect / as sysdba
col filename for a80
col xml for a80
-- Create schema “OTN”
drop user OTN cascade;
purge dba_recyclebin;
create user OTN identified by OTN;
grant dba, xdbadmin to OTN;
EXECUTE dbms_java.grant_permission( 'OTN', 'java.io.FilePermission','G:\OTN\xmlstore','read' );
prompt pause
pause
clear screen
-- Create directory
connect OTN/OTN;
show user
drop directory OTN_USE_CASE;
CREATE directory OTN_USE_CASE AS 'G:\OTN\xmlstore';
SELECT extract((XMLTYPE(bfilename('OTN_USE_CASE','ABANDA-20030407215829881GMT.xml'),NLS_CHARSET_ID('AL32UTF8'))),'*') AS "XML"
from dual;
prompt pause
pause
clear screen
-- Directory Listing - Tom Kyte
create global temporary table DIR_LIST
( filename varchar2(255) )
on commit delete rows
create or replace
and compile java source named "DirList"
as
import java.io.*;
import java.sql.*;
public class DirList
{public static void getList(String directory)
throws SQLException
{ File path = new File( directory );
String[] list = path.list();
String element;
for(int i = 0; i < list.length; i++)
{ element = list;
#sql { INSERT INTO DIR_LIST (FILENAME)
VALUES (:element) };
create or replace procedure get_dir_list( p_directory in varchar2 )
as language java
name 'DirList.getList( java.lang.String )';
prompt pause
pause
clear screen
-- The content of the global temporary table
exec get_dir_list( 'G:\OTN\xmlstore' );
select * from dir_list;
-- "COMMIT" will clear / truncate the global temporary table...
prompt pause
pause
clear screen
-- Combined: Reading XML content from multiple XML files
commit;
exec get_dir_list( 'G:\OTN\xmlstore' );
select * from dir_list where filename like '%.xml'
and rownum <= 10;
prompt pause
pause
clear screen
select extract((XMLTYPE(bfilename('OTN_USE_CASE',dl.filename),NLS_CHARSET_ID('AL32UTF8'))),'*') AS "XML"
from dir_list dl
where dl.filename like '%.xml' and rownum <= 2;
prompt pause
pause
clear screen
-- If you can select it you can insert it...
-- drop table OTN_xml_store purge;
create table OTN_xml_store of xmltype
xmltype store as binary xml
commit;
exec get_dir_list( 'G:\OTN\xmlstore' );
set time on timing on
insert into OTN_xml_store
select XMLTYPE(bfilename('OTN_USE_CASE',dl.filename),NLS_CHARSET_ID('AL32UTF8')) AS "XML"
from dir_list dl
where dl.filename like '%.xml';
set time off timing off
commit;
select count(*) from OTN_xml_store;
prompt pause
pause
clear screen
-- If you can select it you can create resources and files
set time on timing on
commit;
exec get_dir_list( 'G:\OTN\xmlstore' );
select count(*) from dir_list where filename like '%.xml';
set serveroutput on size 10000
DECLARE
XMLdoc XMLType;
res BOOLEAN;
v_foldername varchar2(4000) := '/public/OTN/';
cursor c1
is
select dl.filename FNAME
, XMLTYPE(bfilename('OTN_USE_CASE',dl.filename),NLS_CHARSET_ID('AL32UTF8')) XMLCONTENT
from dir_list dl
where dl.filename like '%.xml'
and rownum <= 100;
BEGIN
-- Create XDB repository Folder
if (dbms_xdb.existsResource(v_foldername))
then
dbms_xdb.deleteResource(v_foldername,dbms_xdb.DELETE_RECURSIVE_FORCE);
end if;
res:=DBMS_XDB.createFolder(v_foldername);
-- Create XML files in the XDB Repository
for r1 in c1
loop
if (DBMS_XDB.CREATERESOURCE(v_foldername||r1.fname, r1.xmlcontent))
then
dbms_output.put_line(v_foldername||r1.fname);
null;
else
dbms_output.put_line('Loop Exception :'||sqlerrm);
end if;
end loop;
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line('Others Exception: '||sqlerrm);
END;
set time off timing off
commit;
prompt pause
pause
clear screen
-- FTP and HTTP
clear screen
prompt
prompt *** FTP - Demo ***
prompt
prompt pause
pause
host ftp
-- open localhost 2100
-- user OTN OTN
-- cd public
-- cd OTN
-- ls
-- bye
clear screen
prompt
prompt *** Microsoft Internet Explorer - Demo ***
prompt
prompt pause
pause
host "C:\Program Files\Internet Explorer\IEXPLORE.EXE" http://OTN:OTN@localhost:8080/public/OTN/
prompt pause
pause
-- Accessing the XDB Repository content via Resource View
-- Selecting content from a resource via XBDUriType
clear screen
prompt set long 300
set long 300
prompt Relative Path - (path)
SELECT path(1) as filename
FROM RESOURCE_VIEW
WHERE under_path(RES, '/public/OTN', 1) = 1
and rownum <= 10
prompt pause
pause
clear screen
prompt Absolute Path - (any_path)
select xdburitype(any_path).getClob() as xml
FROM RESOURCE_VIEW
WHERE under_path(RES, '/public/OTN', 1) = 1
and rownum <= 1;
prompt pause
pause
-- CLEANUP ENVIRONMENT
clear screen
prompt
prompt >>>>> Clean UP !!! <<<<<<
prompt
prompt Cleanup environment and drop user...!!!
prompt
pause
clear screen
conn / as sysdba
alter session set current_schema=OTN;
begin
dbms_xdb.deleteResource('/public/OTN',dbms_xdb.DELETE_RECURSIVE_FORCE);
commit;
end;
alter session set current_schema=sys;
drop user OTN cascade;
Based on http://www.liberidu.com/blog/?p=1053 -
Loading an XML file into the table without creating a directory .
Hi,
I wanted to load an XML file into a table column . But I should not create a directory in the server and placing the XML file there and giving the path in the insert query. Can anybody help me here?
Thanks in advance.You could write a java stored procedure that retrieves the file into a clob. Wrap that in a function call and use it in your insert statement.
This solution require read privileges granted by sys and is therefore only feasible if the top-level directory/directories are known or you get read-access to everything. -
How to load a XML file into a table using PL/SQL
Hi Guru,
I have a requirement, that i have to create a procedure or a package in PL/SQL to load XML file into a table.
How we can achive this.ODI_NewUser wrote:
Hi Guru,
I have a requirement, that i have to create a procedure or a package in PL/SQL to load XML file into a table.
How we can achive this.
Not a perfectly framed question. How do you want to load the XML file? Hoping you want to parse the xml file and load it into a table you can do this.
This is the xml file
karthick% cat emp_details.xml
<?xml version="1.0"?>
<ROWSET>
<ROW>
<EMPNO>7782</EMPNO>
<ENAME>CLARK</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>09-JUN-1981</HIREDATE>
<SAL>2450</SAL>
<COM>0</COM>
<DEPTNO>10</DEPTNO>
</ROW>
<ROW>
<EMPNO>7839</EMPNO>
<ENAME>KING</ENAME>
<JOB>PRESIDENT</JOB>
<HIREDATE>17-NOV-1981</HIREDATE>
<SAL>5000</SAL>
<COM>0</COM>
<DEPTNO>10</DEPTNO>
</ROW>
</ROWSET>
You can write a query like this.
SQL> select *
2 from xmltable
3 (
4 '/ROWSET/ROW' passing xmltype
5 (
6 bfilename('SDAARBORDIRLOG', 'emp_details.xml')
7 , nls_charset_id('AL32UTF8')
8 )
9 columns empno number path 'EMPNO'
10 , ename varchar2(6) path 'ENAME'
11 , job varchar2(9) path 'JOB'
12 , mgr number path 'MGR'
13 , hiredate varchar2(20)path 'HIREDATE'
14 , sal number path 'SAL'
15 , com number path 'COM'
16 , deptno number path 'DEPTNO'
17 );
EMPNO ENAME JOB MGR HIREDATE SAL COM DEPTNO
7782 CLARK MANAGER 7839 09-JUN-1981 2450 0 10
7839 KING PRESIDENT 17-NOV-1981 5000 0 10
SQL> -
How to convert xml file into internal table in ABAP Mapping.
Hi All,
I am trying with ABAP mapping. I have one scenario in which I'm using below xml file as a sender from my FTP server.
<?xml version="1.0" encoding="UTF-8" ?>
- <ns0:MTO_ABAP_MAPPING xmlns:ns0="http://Capgemini/Mumbai/sarsingh">
<BookingCode>2KY34R</BookingCode>
- <Passenger>
<Name>SARVESH</Name>
<Address>THANE</Address>
</Passenger>
- <Passenger>
<Name>RAJESH</Name>
<Address>POWAI</Address>
</Passenger>
- <Passenger>
<Name>CARRON</Name>
<Address>JUHU</Address>
</Passenger>
- <Flight>
<Date>03/03/07</Date>
<AirlineID>UA</AirlineID>
<FlightNumber>125</FlightNumber>
<From>LAS</From>
<To>SFO</To>
</Flight>
</ns0:MTO_ABAP_MAPPING>
AT the receiver side I wnat to concatenate the NAME & ADDRESS.
I tried Robert Eijpe's weblog (/people/r.eijpe/blog/2005/11/21/xml-dom-processing-in-abap-part-ii--convert-an-xml-file-into-an-abap-table-using-sap-dom-approach)
but couldnt succeed to convert the xml file into internal table perfectly.
Can anybody help on this.
Thanks in advance!!
SarveshHi Sarvesh,
The pdf has details of ABAP mapping. The example given almost matches the xml file you want to be converted.
https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/com.sap.km.cm.docs/library/xi/3.0/how to use abap-mapping in xi 3.0.pdf
Just in case you have not seen this
regards
Vijaya -
Loading XML files into Database table
Loading XML files into Database table
Hi I have some XML files say 100 files in a virtual directory created using "Create or replace directory command" and those files need to be loaded into a table having a column of XMLTYPE. 1)How to load that using Oracle provided procedures/packagesCheck out the Oracle XDB Developer's Guide, Chapter 3. There is an example of using BFileName function to load the xml files from a directory object created using create or replace directory. It works really well.
Ben -
Importing data- using xml file into HANA Table
Hi,
We are using (HDB STUDIO ) - revision 60.......
Is it possible to import data using XML file into HANA table (Master,Fact tables)?
(Without using any intermediate adapters for conversion of data.....)
Can any one suggest us........
Thank you.Hi user450616
I am a bit confused about what you are trying to achieve.
Are you:
1. importing a CSV file into APEX
2. adding an extra column to the Oracle Table
3. populating the extra column with the CSV filename?
Let us know if this is what you are trying to do.
Cheers,
Patrick Cimolini -
Insert XML file into Relational database model without using XMLTYPE tables
Dear all,
How can I store a known complex XML file into an existing relational database WITHOUT using xmltypes in the database ?
I read the article on DBMS_XMLSTORE. DBMS_XMLSTORE indeed partially bridges the gap between XML and RDBMS to a certain extent, namely for simply structured XML (canonical structure) and simple tables.
However, when the XML structure will become arbitrary and rapidly evolving, surely there must be a way to map XML to a relational model more flexibly.
We work in a java/Oracle10 environment that receives very large XML documents from an independent data management source. These files comply with an XML schema. That is all we know. Still, all these data must be inserted/updated daily in an existing relational model. Quite an assignment isn't it ?
The database does and will not contain XMLTYPES, only plain RDBMS tables.
Are you aware of a framework/product or tool to do what DBMS_XMLSTORE does but with any format of XML file ? If not, I am doomed.
Constraints : Input via XML files defined by third party
Storage : relational database model with hundreds of tables and thousands of existing queries that can not be touched. The model must not be altered.
Target : get this XML into the database on a daily basis via an automated process.
Cheers.
Luc.Luc,
your Doomed !
If you would try something like DBMS_XMLSTORE, you probably would be into serious performance problems in your case, very fast, and it would be very difficult to manage.
If you would use a little bit of XMLType stuff, you would be able to shred the data into the relational model very fast and controlable. Take it from me, I am one of those old geezers like Mr. Tom Kyte way beyond 40 years (still joking). No seriously. I started out as a classical PL/SQL, Forms Guy that switched after two years to become a "DBA 1.0" and Mr Codd and Mr Date were for years my biggest hero's. I have the utmost respect for Mr. Tom Kyte for all his efforts for bringing the concepts manual into the development world. Just to name some off the names that influenced me. But you will have to work with UNSTRUCTURED data (as Mr Date would call it). 80% of the data out there exists off it. Stuff like XMLTABLE and XML VIEWs bridge the gap between that unstructured world and the relational world. It is very doable to drag and drop an XML file into the XMLDB database into a XMLtype table and or for instance via FTP. From that point on it is in the database. From there you could move into relational tables via XMLTABLE methods or XML Views.
You could see the described method as a filtering option so XML can be transformed into relational data. If you don't want any XML in your current database, then create an small Oracle database with XML DB installed (if doable 11.1.0.7 regarding the best performance --> all the new fast optimizer stuff etc). Use that database as a staging area that does all the XML shredding for you into relational components and ship the end result via database links and or materialized views or other probably known methodes into your relational database that isn't allowed to have XMLType.
This way you would keep your realtional Oracle database clean and have the Oracle XML DB staging database do all the filtering and shredding into relational components.
Throwing the XML DB option out off the window beforehand would be like replacing your Mercedes with a bicycle. With both you will be able to travel the distance from Paris to Rome, but it will take you a hell of lot longer.
:-) -
"PLS-00172: string literal too long" When Writing XML file into a Table
Hi.
I'm using DBMS_XMLStore to get a XML file into a db table. See the example below, I'm using that for my PL/SQL format. Problem is that because there're too many XML elements that I use in "xmldoc CLOB:= ...", I get "PLS-00172: string literal too long" error.
Can someone suggest a workaround?
THANKS!!!
DECLARE
insCtx DBMS_XMLStore.ctxType;
rows NUMBER;
xmldoc CLOB :=
'<ROWSET>
<ROW num="1">
<EMPNO>7369</EMPNO>
<SAL>1800</SAL>
<HIREDATE>27-AUG-1996</HIREDATE>
</ROW>
<ROW>
<EMPNO>2290</EMPNO>
<SAL>2000</SAL>
<HIREDATE>31-DEC-1992</HIREDATE>
</ROW>
</ROWSET>';
BEGIN
insCtx := DBMS_XMLStore.newContext('scott.emp'); -- get saved context
DBMS_XMLStore.clearUpdateColumnList(insCtx); -- clear the update settings
-- set the columns to be updated as a list of values
DBMS_XMLStore.setUpdateColumn(insCtx,'EMPNO');
DBMS_XMLStore.setUpdateColumn(insCtx,'SAL');
DBMS_XMLStore.setUpdatecolumn(insCtx,'HIREDATE');
-- Now insert the doc.
-- This will only insert into EMPNO, SAL and HIREDATE columns
rows := DBMS_XMLStore.insertXML(insCtx, xmlDoc);
-- Close the context
DBMS_XMLStore.closeContext(insCtx);
END;
/You ask where am getting the XML doc. Well, am not
getting the doc itself.I either don't understand or I disagree. In your sample code, you're certainly creating an XML document-- your local variable "xmldoc" is an XML document.
DBMS_XMLSTORE package needs
to know the canonical format and that's what I
hardcoded. Again, I either don't understand or I disagree... DBMS_XMLStore more or less assumes the format of the XML document itself-- there's a ROWSET tag, a ROW tag, and a then whatever column tags you'd like. You can override what tag identifies a row, but the rest is pretty much assumed. Your calls to setUpdateColumn identifies what subset of column tags in the XML document you're interested in.
Later in code I use
DBMS_XMLStore.setUpdateColumn to specify which
columns are to be inserted.Agreed.
xmldoc CLOB :=
'<ROWSET>
<ROW num="1">
<KEY_OLD> Smoker </KEY_OLD>
<KEY_NEW> 3 </KEY_NEW>
<TRANSFORM> Specified </TRANSFORM>
<KEY_OLD> Smoker </KEY_OLD>
<VALUEOLD> -1 </VALUEOLD>
EW> -1 </VALUENEW>
<DESCRIPTION> NA </DESCRIPTION>
</ROW>
ROWSET>';This is your XML document. You almost certainly want to be reading this from the file system and/or have it passed in from another procedure. If you hard-code the XML document, you're limited to a 32k string literal, which is almost certainly causing the error you were reporting initially.
As am writing this I'm realizing that I'm doing this
wrong, because I do need to read the XML file from
the filesystem (but insert the columns
selectively)...What I need to come up with is a proc
that would grab the XML file and do inserts into a
relational table. The XML file will change in the
future and that means that all my 'canonical format'
code will be broken. How do I deal with anticipated
change? Do I need to define/create an XML schema in
10g if am just inserting into one relat. table from
one XML file?What does "The XML file will change in the future" mean? Are you saying that the structure of the XML document will change? Or that the data in the XML document would change? Your code should only need to change if the structure of the document changes, which should be exceptionally uncommon and would only be an issue if you're adding another column that you want to work with, which would necessitate code changes.
I found an article where the issue of changing XML
file is dealt by using a XSL file (that's where I'd
define the 'canonical format'), but am having a
problem with creating one, because the source XML is
screwed up in terms of the format:
it's not <x> blah </x>
<x2> blah </x2>
x2="blah" x3="blah> ...etc
Can you point me in the right direction, please?You can certainly use something like the DBMS_XSLProcessor package to transform whatever XML document you have into an XML document in an appropriate format for the XMLStore package and pass that transformed XML document into something like your sample procedure rather than defining the xmldoc local variable with a hard-coded document. Of course, you'd need to write appropriate XSL code to do the actual transform.
Justin -
Insert XML file into Relational database model - no XMLTYPE!
Dear all,
How can I store a known complex XML file into an existing relational database WITHOUT using xmltypes in the database ?
I read the article on DBMS_XMLSTORE. DBMS_XMLSTORE indeed partially bridges the gap between XML and RDBMS to a certain extent, namely for simply structured XML (canonical structure) and simple tables.
However, when the XML structure will become arbitrary and rapidly evolving, surely there must be a way to map XML to a relational model more flexibly.
We work in a java/Oracle10 environment that receives very large XML documents from an independent data management source. These files comply with an XML schema. That is all we know. Still, all these data must be inserted/updated daily in an existing relational model. Quite an assignment isn't it ?
The database does and will not contain XMLTYPES, only plain RDBMS tables.
Are you aware of a framework/product or tool to do what DBMS_XMLSTORE does but with any format of XML file ? If not, I am doomed.
Cheers.
Luc.
Edited by: user6693852 on Jan 13, 2009 7:02 AMIn case you decide to follow my advice, here's a simple example showing how to do this.. (Note the XMLTable syntax is the preferred approach in 10gr2 and later..
SQL> spool testase.log
SQL> --
SQL> connect / as sysdba
Connected.
SQL> --
SQL> set define on
SQL> set timing on
SQL> --
SQL> define USERNAME = XDBTEST
SQL> --
SQL> def PASSWORD = XDBTEST
SQL> --
SQL> def USER_TABLESPACE = USERS
SQL> --
SQL> def TEMP_TABLESPACE = TEMP
SQL> --
SQL> drop user &USERNAME cascade
2 /
old 1: drop user &USERNAME cascade
new 1: drop user XDBTEST cascade
User dropped.
Elapsed: 00:00:00.59
SQL> grant create any directory, drop any directory, connect, resource, alter session, create view to &USERNAME identified by &PASS
ORD
2 /
old 1: grant create any directory, drop any directory, connect, resource, alter session, create view to &USERNAME identified by &
ASSWORD
new 1: grant create any directory, drop any directory, connect, resource, alter session, create view to XDBTEST identified by XDB
EST
Grant succeeded.
Elapsed: 00:00:00.01
SQL> alter user &USERNAME default tablespace &USER_TABLESPACE temporary tablespace &TEMP_TABLESPACE
2 /
old 1: alter user &USERNAME default tablespace &USER_TABLESPACE temporary tablespace &TEMP_TABLESPACE
new 1: alter user XDBTEST default tablespace USERS temporary tablespace TEMP
User altered.
Elapsed: 00:00:00.00
SQL> connect &USERNAME/&PASSWORD
Connected.
SQL> --
SQL> var SCHEMAURL varchar2(256)
SQL> var XMLSCHEMA CLOB
SQL> --
SQL> set define off
SQL> --
SQL> begin
2 :SCHEMAURL := 'http://xmlns.example.com/askTom/TransactionList.xsd';
3 :XMLSCHEMA :=
4 '<?xml version="1.0" encoding="UTF-8"?>
5 <!--W3C Schema generated by XMLSpy v2008 rel. 2 sp2 (http://www.altova.com)-->
6 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xdb="http://xmlns.oracle.com/xdb" xdb:storeVarrayAsTable="true">
7 <xs:element name="TransactionList" type="transactionListType" xdb:defaultTable="LOCAL_TABLE"/>
8 <xs:complexType name="transactionListType" xdb:maintainDOM="false" xdb:SQLType="TRANSACTION_LIST_T">
9 <xs:sequence>
10 <xs:element name="Transaction" type="transactionType" maxOccurs="unbounded" xdb:SQLCollType="TRANSACTION_V"
>
11 </xs:sequence>
12 </xs:complexType>
13 <xs:complexType name="transactionType" xdb:maintainDOM="false" xdb:SQLType="TRANSACTION_T">
14 <xs:sequence>
15 <xs:element name="TradeVersion" type="xs:integer"/>
16 <xs:element name="TransactionId" type="xs:integer"/>
17 <xs:element name="Leg" type="legType" maxOccurs="unbounded" xdb:SQLCollType="LEG_V"/>
18 </xs:sequence>
19 <xs:attribute name="id" type="xs:integer" use="required"/>
20 </xs:complexType>
21 <xs:complexType name="paymentType" xdb:maintainDOM="false" xdb:SQLType="PAYMENT_T">
22 <xs:sequence>
23 <xs:element name="StartDate" type="xs:date"/>
24 <xs:element name="Value" type="xs:integer"/>
25 </xs:sequence>
26 <xs:attribute name="id" type="xs:integer" use="required"/>
27 </xs:complexType>
28 <xs:complexType name="legType" xdb:maintainDOM="false" xdb:SQLType="LEG_T">
29 <xs:sequence>
30 <xs:element name="LegNumber" type="xs:integer"/>
31 <xs:element name="Basis" type="xs:integer"/>
32 <xs:element name="FixedRate" type="xs:integer"/>
33 <xs:element name="Payment" type="paymentType" maxOccurs="unbounded" xdb:SQLCollType="PAYMENT_V"/>
34 </xs:sequence>
35 <xs:attribute name="id" type="xs:integer" use="required"/>
36 </xs:complexType>
37 </xs:schema>';
38 end;
39 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.00
SQL> set define on
SQL> --
SQL> declare
2 res boolean;
3 xmlSchema xmlType := xmlType(:XMLSCHEMA);
4 begin
5 dbms_xmlschema.registerSchema
6 (
7 schemaurl => :schemaURL,
8 schemadoc => xmlSchema,
9 local => TRUE,
10 genTypes => TRUE,
11 genBean => FALSE,
12 genTables => TRUE,
13 ENABLEHIERARCHY => DBMS_XMLSCHEMA.ENABLE_HIERARCHY_NONE
14 );
15 end;
16 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.26
SQL> desc LOCAL_TABLE
Name Null? Type
TABLE of SYS.XMLTYPE(XMLSchema "http://xmlns.example.com/askTom/TransactionList.xsd" Element "TransactionList") STORAGE Object-rela
ional TYPE "TRANSACTION_LIST_T"
SQL> --
SQL> create or replace VIEW TRAN_VIEW
2 as
3 select
4 extractvalue(x.column_value,'/Transaction/TradeVersion/text()') tradeversion,
5 extractvalue(x.column_value,'/Transaction//text()') transactionid
6 from
7 local_table,
8 table(xmlsequence(extract(OBJECT_VALUE,'/TransactionList/Transaction'))) x
9 /
View created.
Elapsed: 00:00:00.01
SQL> create or replace VIEW TRAN_LEG_VIEW
2 as
3 select
4 extractvalue(x.column_value,'/Transaction/TransactionId/text()') transactionid,
5 extractvalue(y.column_value,'/Leg/Basis/text()') leg_basis,
6 extractValue(y.column_value,'/Leg/FixedRate/text()') leg_fixedrate
7 from
8 local_table,
9 table(xmlsequence(extract(OBJECT_VALUE,'/TransactionList/Transaction'))) x,
10 table(xmlsequence(extract(x.column_value,'/Transaction/Leg'))) y
11 /
View created.
Elapsed: 00:00:00.01
SQL> create or replace VIEW TRAN_LEG_PAY_VIEW
2 as
3 select
4 extractvalue(x.column_value,'/Transaction/TransactionId/text()') transactionid,
5 extractvalue(y.column_value,'/Leg/LegNumber/text()') leg_legnumber,
6 extractvalue(z.column_value,'/Payment/StartDate/text()') pay_startdate,
7 extractValue(z.column_value,'/Payment/Value/text()') pay_value
8 from
9 local_table,
10 table(xmlsequence(extract(OBJECT_VALUE,'/TransactionList/Transaction'))) x,
11 table(xmlsequence(extract(x.column_value,'/Transaction/Leg'))) y,
12 table(xmlsequence(extract(y.column_value,'/Leg/Payment'))) z
13 /
View created.
Elapsed: 00:00:00.03
SQL> desc TRAN_VIEW
Name Null? Type
TRADEVERSION NUMBER(38)
TRANSACTIONID VARCHAR2(4000)
SQL> --
SQL> desc TRAN_LEG_VIEW
Name Null? Type
TRANSACTIONID NUMBER(38)
LEG_BASIS NUMBER(38)
LEG_FIXEDRATE NUMBER(38)
SQL> --
SQL> desc TRAN_LEG_PAY_VIEW
Name Null? Type
TRANSACTIONID NUMBER(38)
LEG_LEGNUMBER NUMBER(38)
PAY_STARTDATE DATE
PAY_VALUE NUMBER(38)
SQL> --
SQL> create or replace VIEW TRAN_VIEW_XMLTABLE
2 as
3 select t.*
4 from LOCAL_TABLE,
5 XMLTable
6 (
7 '/TransactionList/Transaction'
8 passing OBJECT_VALUE
9 columns
10 TRADE_VERSION NUMBER(4) path 'TradeVersion/text()',
11 TRANSACTION_ID NUMBER(4) path 'TransactionId/text()'
12 ) t
13 /
View created.
Elapsed: 00:00:00.01
SQL> create or replace VIEW TRAN_LEG_VIEW_XMLTABLE
2 as
3 select t.TRANSACTION_ID, L.*
4 from LOCAL_TABLE,
5 XMLTable
6 (
7 '/TransactionList/Transaction'
8 passing OBJECT_VALUE
9 columns
10 TRANSACTION_ID NUMBER(4) path 'TransactionId/text()',
11 LEG XMLType path 'Leg'
12 ) t,
13 XMLTABLE
14 (
15 '/Leg'
16 passing LEG
17 columns
18 LEG_NUMBER NUMBER(4) path 'LegNumber/text()',
19 LEG_BASIS NUMBER(4) path 'Basis/text()',
20 LEG_FIXED_RATE NUMBER(4) path 'FixedRate/text()'
21 ) l
22 /
View created.
Elapsed: 00:00:00.01
SQL> create or replace VIEW TRAN_LEG_PAY_VIEW_XMLTABLE
2 as
3 select TRANSACTION_ID, L.LEG_NUMBER, P.*
4 from LOCAL_TABLE,
5 XMLTable
6 (
7 '/TransactionList/Transaction'
8 passing OBJECT_VALUE
9 columns
10 TRANSACTION_ID NUMBER(4) path 'TransactionId/text()',
11 LEG XMLType path 'Leg'
12 ) t,
13 XMLTABLE
14 (
15 '/Leg'
16 passing LEG
17 columns
18 LEG_NUMBER NUMBER(4) path 'LegNumber/text()',
19 PAYMENT XMLType path 'Payment'
20 ) L,
21 XMLTABLE
22 (
23 '/Payment'
24 passing PAYMENT
25 columns
26 PAY_START_DATE DATE path 'StartDate/text()',
27 PAY_VALUE NUMBER(4) path 'Value/text()'
28 ) p
29 /
View created.
Elapsed: 00:00:00.03
SQL> desc TRAN_VIEW_XMLTABLE
Name Null? Type
TRADE_VERSION NUMBER(4)
TRANSACTION_ID NUMBER(4)
SQL> --
SQL> desc TRAN_LEG_VIEW_XMLTABLE
Name Null? Type
TRANSACTION_ID NUMBER(4)
LEG_NUMBER NUMBER(4)
LEG_BASIS NUMBER(4)
LEG_FIXED_RATE NUMBER(4)
SQL> --
SQL> desc TRAN_LEG_PAY_VIEW_XMLTABLE
Name Null? Type
TRANSACTION_ID NUMBER(4)
LEG_NUMBER NUMBER(4)
PAY_START_DATE DATE
PAY_VALUE NUMBER(4)
SQL> --
SQL> set long 10000 pages 100 lines 128
SQL> set timing on
SQL> set autotrace on explain
SQL> set heading on feedback on
SQL> --
SQL> VAR DOC1 CLOB
SQL> VAR DOC2 CLOB
SQL> --
SQL> begin
2 :DOC1 :=
3 '<TransactionList>
4 <Transaction id="1">
5 <TradeVersion>1</TradeVersion>
6 <TransactionId>1</TransactionId>
7 <Leg id="1">
8 <LegNumber>1</LegNumber>
9 <Basis>1</Basis>
10 <FixedRate>1</FixedRate>
11 <Payment id="1">
12 <StartDate>2000-01-01</StartDate>
13 <Value>1</Value>
14 </Payment>
15 <Payment id="2">
16 <StartDate>2000-01-02</StartDate>
17 <Value>2</Value>
18 </Payment>
19 </Leg>
20 <Leg id="2">
21 <LegNumber>2</LegNumber>
22 <Basis>2</Basis>
23 <FixedRate>2</FixedRate>
24 <Payment id="1">
25 <StartDate>2000-02-01</StartDate>
26 <Value>10</Value>
27 </Payment>
28 <Payment id="2">
29 <StartDate>2000-02-02</StartDate>
30 <Value>20</Value>
31 </Payment>
32 </Leg>
33 </Transaction>
34 <Transaction id="2">
35 <TradeVersion>2</TradeVersion>
36 <TransactionId>2</TransactionId>
37 <Leg id="1">
38 <LegNumber>21</LegNumber>
39 <Basis>21</Basis>
40 <FixedRate>21</FixedRate>
41 <Payment id="1">
42 <StartDate>2002-01-01</StartDate>
43 <Value>21</Value>
44 </Payment>
45 <Payment id="2">
46 <StartDate>2002-01-02</StartDate>
47 <Value>22</Value>
48 </Payment>
49 </Leg>
50 <Leg id="22">
51 <LegNumber>22</LegNumber>
52 <Basis>22</Basis>
53 <FixedRate>22</FixedRate>
54 <Payment id="21">
55 <StartDate>2002-02-01</StartDate>
56 <Value>210</Value>
57 </Payment>
58 <Payment id="22">
59 <StartDate>2002-02-02</StartDate>
60 <Value>220</Value>
61 </Payment>
62 </Leg>
63 </Transaction>
64 </TransactionList>';
65 :DOC2 :=
66 '<TransactionList>
67 <Transaction id="31">
68 <TradeVersion>31</TradeVersion>
69 <TransactionId>31</TransactionId>
70 <Leg id="31">
71 <LegNumber>31</LegNumber>
72 <Basis>31</Basis>
73 <FixedRate>31</FixedRate>
74 <Payment id="31">
75 <StartDate>3000-01-01</StartDate>
76 <Value>31</Value>
77 </Payment>
78 </Leg>
79 </Transaction>
80 </TransactionList>';
81 end;
82 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.01
SQL> insert into LOCAL_TABLE values ( xmltype(:DOC1))
2 /
1 row created.
Elapsed: 00:00:00.01
Execution Plan
Plan hash value: 1
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | INSERT STATEMENT | | 1 | 100 | 1 (0)| 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | LOCAL_TABLE | | | | |
SQL> insert into LOCAL_TABLE values ( xmltype(:DOC2))
2 /
1 row created.
Elapsed: 00:00:00.01
Execution Plan
Plan hash value: 1
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | INSERT STATEMENT | | 1 | 100 | 1 (0)| 00:00:01 |
| 1 | LOAD TABLE CONVENTIONAL | LOCAL_TABLE | | | | |
SQL> select * from TRAN_VIEW_XMLTABLE
2 /
TRADE_VERSION TRANSACTION_ID
1 1
2 2
31 31
3 rows selected.
Elapsed: 00:00:00.03
Execution Plan
Plan hash value: 650975545
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 3 | 168 | 3 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 3 | 168 | 3 (0)| 00:00:01 |
|* 2 | TABLE ACCESS FULL| SYS_NTGgl+TKyhQnWoFRSrCxeX9g== | 3 | 138 | 3 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN| SYS_C0010174 | 1 | 10 | 0 (0)| 00:00:01 |
Predicate Information (identified by operation id):
2 - filter("SYS_NC_TYPEID$" IS NOT NULL)
3 - access("NESTED_TABLE_ID"="LOCAL_TABLE"."SYS_NC0000800009$")
Note
- dynamic sampling used for this statement
SQL> select * from TRAN_LEG_VIEW_XMLTABLE
2 /
TRANSACTION_ID LEG_NUMBER LEG_BASIS LEG_FIXED_RATE
1 1 1 1
1 2 2 2
2 21 21 21
2 22 22 22
31 31 31 31
5 rows selected.
Elapsed: 00:00:00.04
Execution Plan
Plan hash value: 1273661583
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 5 | 560 | 7 (15)| 00:00:01 |
|* 1 | HASH JOIN | | 5 | 560 | 7 (15)| 00:00:01 |
| 2 | NESTED LOOPS | | 3 | 159 | 3 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL| SYS_NTGgl+TKyhQnWoFRSrCxeX9g== | 3 | 129 | 3 (0)| 00:00:01 |
|* 4 | INDEX UNIQUE SCAN| SYS_C0010174 | 1 | 10 | 0 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | SYS_NTUmyermF/S721C/2UXo40Uw== | 5 | 295 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("SYS_ALIAS_1"."NESTED_TABLE_ID"="SYS_ALIAS_0"."SYS_NC0000800009$")
3 - filter("SYS_NC_TYPEID$" IS NOT NULL)
4 - access("NESTED_TABLE_ID"="LOCAL_TABLE"."SYS_NC0000800009$")
5 - filter("SYS_NC_TYPEID$" IS NOT NULL)
Note
- dynamic sampling used for this statement
SQL> select * from TRAN_LEG_PAY_VIEW_XMLTABLE
2 /
TRANSACTION_ID LEG_NUMBER PAY_START PAY_VALUE
1 1 01-JAN-00 1
1 1 02-JAN-00 2
1 2 01-FEB-00 10
1 2 02-FEB-00 20
2 21 01-JAN-02 21
2 21 02-JAN-02 22
2 22 01-FEB-02 210
2 22 02-FEB-02 220
31 31 01-JAN-00 31
9 rows selected.
Elapsed: 00:00:00.07
Execution Plan
Plan hash value: 4004907785
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 9 | 1242 | 10 (10)| 00:00:01 |
|* 1 | HASH JOIN | | 9 | 1242 | 10 (10)| 00:00:01 |
|* 2 | HASH JOIN | | 5 | 480 | 7 (15)| 00:00:01 |
| 3 | NESTED LOOPS | | 3 | 159 | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS FULL| SYS_NTGgl+TKyhQnWoFRSrCxeX9g== | 3 | 129 | 3 (0)| 00:00:01 |
|* 5 | INDEX UNIQUE SCAN| SYS_C0010174 | 1 | 10 | 0 (0)| 00:00:01 |
|* 6 | TABLE ACCESS FULL | SYS_NTUmyermF/S721C/2UXo40Uw== | 5 | 215 | 3 (0)| 00:00:01 |
|* 7 | TABLE ACCESS FULL | SYS_NTelW4ZRtKS+WKqCaXhsHnNQ== | 9 | 378 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - access("NESTED_TABLE_ID"="SYS_ALIAS_1"."SYS_NC0000900010$")
2 - access("SYS_ALIAS_1"."NESTED_TABLE_ID"="SYS_ALIAS_0"."SYS_NC0000800009$")
4 - filter("SYS_NC_TYPEID$" IS NOT NULL)
5 - access("NESTED_TABLE_ID"="LOCAL_TABLE"."SYS_NC0000800009$")
6 - filter("SYS_NC_TYPEID$" IS NOT NULL)
7 - filter("SYS_NC_TYPEID$" IS NOT NULL)
Note
- dynamic sampling used for this statement
SQL>Out of interest why are you so against using XMLType...
Edited by: mdrake on Jan 13, 2009 8:25 AM -
Insert Insert XML file into multiple records in Oracle Database
I would like to find out if it is possible to insert a single XML file into multiple records or tuples in a Oracle database table. I have a single XML file which is at multiple levels. The meta data for the levels are common and each level can have meta data of their own in addition. I do not have any meta data field which will uniquely determine whether the data belongs to Root level, Intermediate level or at the document level. Is there any way I can determine which level the meta data belongs to and thereby make a corresponding entry into the database table tuple? For example I could have an attribute called level which is going to be present only in the database table and not in the XML file. If level=1 then it corresponds to "Root" meta data, if level=2 then it corresponds to "Intermediate" level and if level=3 then it corresponds to meta data at document level. I need a way to calculate the value for level from the XML file and thereby insert the meta data element into a tuple in a single table in Oracle.
Hi,
extract your xml and then you can use insert all clause.
here's very small example on 10.2.0.1.0
SQL> create table table1(id number,val varchar2(10));
Table created.
SQL> create table table2(id number,val varchar2(10));
Table created.
SQL> insert all
2 into table1 values(id,val)
3 into table2 values(id2,val2)
4 select extractValue(x.col,'/a/id1') id
5 ,extractValue(x.col,'/a/value') val
6 ,extractValue(x.col,'/a/value2') val2
7 ,extractValue(x.col,'/a/id2') id2
8 from (select xmltype('<a><id1>1</id1><value>a</value><id2>2</id2><value2>b</value2></a>') col from dual) x;
2 rows created.
SQL> select * from table1;
ID VAL
1 a
SQL> select * from table2;
ID VAL
2 b Ants -
How do I upload XML files into sap table?
Dear all,
I found some methods that upload xml into SAP,
but there doesnt work under 4.6c.
Can someone tell me how to upload XML files into
sap under 4.6c?
THX!hi,
You can convert XML to abap using transformations. Simple transformations is a proprietary SAP programming language that describes the transformation of ABAP data to XML (serialization) and from XML to ABAP data (deserialization).
goto SE80->workbench->edit object(or other objects)->in object selection chose more tab and then choose the transformation radio button and write a name and click create new.
Here you enter your transformation like
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:transform>
You can use this transfomation in your program using call transformation. You can find more info on call transformation in help.
Hope this helps.
Regards,
Richa -
Load XML File into temporary tables using sql loader
Hi All,
I have an XML file as below. I need to insert the contents into a temporary staging table using sql loader. Please advice how I need to do that.
For example Portfolios should go into a seperate table, and all the tags inside it should be populated in the columns of the table.
Family should go into a seperate table and all the tags inside it should be populated in the columns of the table.
Similarly offer, Products etc.
- <ABSProductCatalog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ProductSalesHierachy>
- <Portfolios>
- <Portfolio productCode="P1">
<Attribute name="CatalogProductName" value="Access" />
<Attribute name="Status" value="Active" />
</Portfolio>
- <Portfolio productCode="P2">
<Attribute name="CatalogProductName" value="Data" />
<Attribute name="Status" value="Active" />
</Portfolio>
- <Portfolio productCode="P3">
<Attribute name="CatalogProductName" value="Voice" />
<Attribute name="Status" value="Active" />
</Portfolio>
- <Portfolio productCode="P4">
<Attribute name="CatalogProductName" value="Wireless" />
<Attribute name="Status" value="Active" />
</Portfolio>
</Portfolios>
- <Families>
- <Family productCode="F1">
<Attribute name="CatalogProductName" value="Internet Access Services" />
<Attribute name="Status" value="Active" />
- <ParentHierarchy>
<Item productCode="P1" modelType="Portfolio" />
</ParentHierarchy>
</Family>
- <Family productCode="F2">
<Attribute name="CatalogProductName" value="Local Access Services" />
<Attribute name="Status" value="Active" />
- <ParentHierarchy>
<Item productCode="P2" modelType="Portfolio" />
</ParentHierarchy>
</Family>
</Families>
- <SubFamilies>
- <SubFamily productCode="SF1">
<Attribute name="CatalogProductName" value="Business Internet service" />
<Attribute name="Status" value="Active" />
- <ParentHierarchy>
<Item productCode="F1" modelType="Family" />
</ParentHierarchy>
</SubFamily>
</SubFamilies>
- <ProductRefs>
- <ProductRef productCode="WSP1" modelType="Wireline Sales Product">
<ActiveFlag>Y</ActiveFlag>
- <ProductHierarchy>
<SalesHierarchy family="F1" subFamily="SF1" portfolio="P1" primary="Y" />
<SalesHierarchy family="F2" portfolio="P2" primary="N" />
<FinancialHierarchy quotaBucket="Voice" strategicProdCategory="Local Voice" />
</ProductHierarchy>
</ProductRef>
- <ProductRef productCode="MSP2" modelType="Handset">
<ActiveFlag>Y</ActiveFlag>
- <ProductHierarchy>
<SalesHierarchy portfolio="P4" primary="Y" />
</ProductHierarchy>
</ProductRef>
</ProductRefs>
</ProductSalesHierachy>
- <Offers>
- <Offer productCode="ABN">
<OfferName>ABN</OfferName>
<OfferDescription>ABN Description</OfferDescription>
- <Segments>
<Segment>SCG</Segment>
<Segment>PCG</Segment>
</Segments>
<OfferUpdateDate>2009-11-20</OfferUpdateDate>
<ActiveFlag>Y</ActiveFlag>
</Offer>
- <Offer productCode="OneNet">
<OfferName>OneNet</OfferName>
<OfferDescription>OneNet Description</OfferDescription>
- <Segments>
<Segment>SCG</Segment>
<Segment>PCG</Segment>
<Segment>PCG2</Segment>
</Segments>
<OfferUpdateDate>2009-11-20</OfferUpdateDate>
<ActiveFlag>Y</ActiveFlag>
</Offer>
</Offers>
- <Products>
- <Product productCode="WSP1" modelType="Wireline Sales Product">
<ProductName>AT&T High Speed Internet</ProductName>
<ProductDescription>High Speed Internet</ProductDescription>
<LegacyCoProdIndicator>SBC</LegacyCoProdIndicator>
<RevenueCBLCode>1234B</RevenueCBLCode>
<VolumeCBLCode>4567A</VolumeCBLCode>
<SAARTServiceIDCode>S1234</SAARTServiceIDCode>
<MarginPercentRequired>Y</MarginPercentRequired>
<PercentIntl>%234</PercentIntl>
<UOM>Each</UOM>
<PriceType>OneTime</PriceType>
<ProductStatus>Active</ProductStatus>
<Compensable>Y</Compensable>
<Jurisdiction>Everywhere</Jurisdiction>
<ActiveFlag>Y</ActiveFlag>
- <Availabilities>
<Availability>SE</Availability>
<Availability>E</Availability>
</Availabilities>
- <Segments>
<Segment>SCG</Segment>
<Segment>PCG</Segment>
</Segments>
<VDIndicator>Voice</VDIndicator>
<PSOCCode>PSOC 1</PSOCCode>
<USBilled>Y</USBilled>
<MOWBilled>N</MOWBilled>
<ProductStartDate>2009-11-20</ProductStartDate>
<ProductUpdateDate>2009-11-20</ProductUpdateDate>
<ProductEndDate>2010-11-20</ProductEndDate>
- <AliasNames>
<AliasName>AT&T HSI</AliasName>
<AliasName>AT&T Fast Internet</AliasName>
</AliasNames>
- <OfferTypes>
<OfferType productCode="ABN" endDate="2009-11-20" />
<OfferType productCode="OneNet" />
</OfferTypes>
- <DynamicAttributes>
- <DynamicAttribute dataType="String" defaultValue="2.5 Mbps" name="Speed">
<AttrValue>1.5 Mbps</AttrValue>
<AttrValue>2.5 Mbps</AttrValue>
<AttrValue>3.5 Mbps</AttrValue>
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="TransportType">
<AttrValue>T1</AttrValue>
</DynamicAttribute>
</DynamicAttributes>
</Product>
- <Product productCode="MSP2" modelType="Handset">
<ProductName>Blackberry Bold</ProductName>
<ProductDescription>Blackberry Bold Phone</ProductDescription>
<LegacyCoProdIndicator />
<RevenueCBLCode />
<VolumeCBLCode />
<SAARTServiceIDCode />
<MarginPercentRequired />
<PercentIntl />
<UOM>Each</UOM>
<PriceType />
<ProductStatus>Active</ProductStatus>
<Compensable />
<Jurisdiction />
<ActiveFlag>Y</ActiveFlag>
- <Availabilities>
<Availability />
</Availabilities>
- <Segments>
<Segment>SCG</Segment>
<Segment>PCG</Segment>
</Segments>
<VDIndicator>Voice</VDIndicator>
<PSOCCode />
<USBilled />
<MOWBilled />
<ProductStartDate>2009-11-20</ProductStartDate>
<ProductUpdateDate>2009-11-20</ProductUpdateDate>
- <AliasNames>
<AliasName />
</AliasNames>
- <OfferTypes>
<OfferType productCode="ABN" />
</OfferTypes>
- <DynamicAttributes>
- <DynamicAttribute dataType="String" name="StlmntContractType">
<AttrValue />
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="BMG 2 year price">
<AttrValue>20</AttrValue>
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="MSRP">
<AttrValue>40</AttrValue>
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="BMGAvailableType">
<AttrValue />
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="ProductId">
<AttrValue>123456</AttrValue>
</DynamicAttribute>
- <DynamicAttribute dataType="String" name="modelSource">
<AttrValue>product</AttrValue>
</DynamicAttribute>
</DynamicAttributes>
</Product>
</Products>
<CatalogChanged>Y</CatalogChanged>
</ABSProductCatalog>Two options that come to mind. Others exist.
#1 - {thread:id=474031}, which is basically storing the XML in an Object Relational structure for parsing
#2 - Dump the XML into either an XMLType based table or column and use SQL (with XMLTable) to create a view that parses the data. This would be the same as the view shown in the above post.
Don't use sql*loader to parse the XML. I was trying to find a post from mdrake about that but couldn't. In short, sql*loader was not build as an XML parser so don't try to use it that way. -
Loading XML files into multiple tables
I've got XML like so...
<?xml version="1.0" encoding="UTF-8"?>
<MainTitle Version="1.0" Date="2009-01-11">
<MainName>
<ID1>A</ID1>
<ID2>ABC</ID2>
<ID3>ABC123</ID3>
<Desc>Some text</Desc>
<feature>f1</feature>
<feature>f2</feature>
<Category>
<name>n1</name>
<attribute>more stuff</attribute>
</Category>
<Category>
<name>n2</name>
<attribute>even more stuff</attribute>
</Category>
<Category>
<name>n3</name>
<attribute>different stuff</attribute>
</Category>
<Category>
<name>n4</name>
<attribute>More of the same<attribute>
<attribute>But different still</attribute>
<attribute>Even more different junk<attribute>
</Category>
</MainName>
</MainTitle>
Where each MainName instance in the file can have 0 or more ( unbounded ) Category and Feature tags and each Category instance can have multiple attribute tags. The file contains many thousands of MainName instances and has embedded a good mix of possible tags.
I believe I can load this into 9i xmltype table or a 9i table with an xmltype column, then query the data to get it out...
SQL> create table mytab (
2 xmlraw XMLType
3 );
Table created.
SQL>
SQL> insert into mytab values ( sys.xmltype.createxml(
2 '<?xml version="1.0" encoding="UTF-8"?>
3 <MainTitle Version="1.0" Date="2009-01-11">
4 <MainName>
5 <ID1>A</ID1>
6 <ID2>ABC</ID2>
7 <ID3>ABC123</ID3>
8 <Desc>Some text</Desc>
9 <feature>f1</feature>
10 <feature>f2</feature>
11 <Category>
12 <name>n1</name>
13 <attribute>more stuff</attribute>
14 </Category>
15 <Category>
16 <name>n2</name>
17 <attribute>even more stuff</attribute>
18 </Category>
19 <Category>
20 <name>n3</name>
21 <attribute>different stuff</attribute>
22 </Category>
23 <Category>
24 <name>n4</name>
25 <attribute>More of the same</attribute>
26 <attribute>But different still</attribute>
27 <attribute>Even more different junk</attribute>
28 </Category>
29 </MainName>
30 </MainTitle>')
31 );
1 row created.
1 select
2 extract(a.xmlraw,'/MainTitle/MainName/ID1/text()'),
3 extract(a.xmlraw,'/MainTitle/MainName/ID2/text()'),
4 extract(a.xmlraw,'/MainTitle/MainName/ID3/text()'),
5 extract(a.xmlraw,'/MainTitle/MainName/Desc/text()'),
6 extract(a.xmlraw,'/MainTitle/MainName/feature/text()'),
7 extract(a.xmlraw,'/MainTitle/MainName/Category/text()'),
8 extract(a.xmlraw,'/MainTitle/MainName/Category/name/text()'),
9 extract(a.xmlraw,'/MainTitle/MainName/Category/attribute/text()')
10* from mytab a
SQL> /
A
ABC
ABC123
Some text
f1f2
n1n2n3n4
more stuffeven more stuffdifferent stuffMore of the sameBut different stillEven
more different junk
This all works just fine, however, it's not quite what I need. For starters, the multiple tag data is concatenated and when I try to specifically query it out using a where clause I get ORA 22950. So, not sure how to deal with that.
Is it possible to use sqlldr to get the 200MB XML file loaded into a table like that above?
Now, given multiple "feature" and "category" data per "MainName", I need to use the SQL to dump the XML data into a set of tables built to model the structure of the XML...
roughly..
Main_Table (
ID1 Varchar2(10)
ID2 varchar2(10)
ID3 varchar2(10)
desc varchar2(100)
Features_Table (
ID1 varchar2(10)
feature varchar2(100)
Category_Table (
ID1 varchar2(10)
name varchar2(100)
attribute varchar2(100)
What are the groups recommendations here? Should I continue down this route or is there a better way?When I suggested the option to parse the XML in PL/SQL I was referring to pulling the data into PL/SQL and then performing all parsing activity against the PL/SQL copy and you don't need to make SQL calls.
Here is a quick sample for parsing out all the Category/name elements from the XML once it is loaded into PL/SQL
DECLARE
l_index PLS_INTEGER;
l_category XMLTYPE;
l_db_row XMLTYPE := XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<MainTitle Version="1.0" Date="2009-01-11">
<MainName>
<ID1>A</ID1>
<ID2>ABC</ID2>
<ID3>ABC123</ID3>
<Desc>Some text</Desc>
<feature>f1</feature>
<feature>f2</feature>
<Category>
<name>n1</name>
<attribute>more stuff</attribute>
</Category>
<Category>
<name>n2</name>
<attribute>even more stuff</attribute>
</Category>
<Category>
<name>n3</name>
<attribute>different stuff</attribute>
</Category>
<Category>
<name>n4</name>
<attribute>More of the same</attribute>
<attribute>But different still</attribute>
<attribute>Even more different junk</attribute>
</Category>
</MainName>
</MainTitle>');
BEGIN
l_index := 1;
WHILE l_db_row.Existsnode('/MainTitle/MainName/Category[' ||
To_Char(l_index) || ']') > 0
LOOP
l_category := l_db_row.Extract('/MainTitle/MainName/Category[' ||
To_Char(l_index) || ']');
dbms_output.put_line(l_category.extract('Category/name/text()').getStringVal());
l_index := l_index + 1;
END LOOP;
END;You could repeat the WHILE loop to parse out the attribute column as well since it repeats. This is what Dave's post was showing and what I was referring to.
Hint: If you are trying to use .extract to go after an optional node, you need to verify the node exists via existsNode first. If you don't you can get an "ORA-30625: method dispatch on NULL SELF argument is disallowed" error when trying to extract a non-existent node.
Maybe you are looking for
-
Import of the iTunes library to a different disk-name
Sorry for doubleposting if a similar post has been made, couldn't find any. After buying a new computer i need to move my music. On the old computer, i got my iTunes library in my itunes folder (on drive c:) and then all my music in a different folde
-
Satellite Pro 4340DVD will not boot up - pci.sys missing or corrupt
I bought a Toshiba Laptop Satellite Pro 4340DVD Model # PS434C-3N152, Serial # Y0018185J, off E-Bay. The original operating system, Win 98SE has been upgraded to Win XP Pro. No disks came with the laptop. The laptop crashed yesterday while I was onli
-
Oracle Tomcat Connection Problem
Dear all, We have Oracle as the back end and Java-Jsp-Struts as the front end for our project.For the last few days we are facing a strange problem and although we tried a lot we were not able to find even the cause of the problem We have Oracle serv
-
How to remove vestiges of Classic ?
I recently installed Leopard on an iMac G5 which came to me with Panther re-installed by the previous owner. I am trying to install an Epson printer (Epson Stylus Photo R200) but it will not open "because the classic environment is no longer supporte
-
Safari will no longer load any images in the browser. What could be the problem?
In the last couple of months safari will no longer load any type of image in the browser. All the text loads fine and the layout is correct but everywhere there should be a picture of any sort is blank. what can I do to fix this?