Quantcast
Channel: Gokhan Atil – Gokhan Atil’s Blog
Viewing all articles
Browse latest Browse all 108

How to Import Data (to Oracle RDBMS) from XML

$
0
0

I wrote a blog post about how to import data from a XML file to Oracle about 7 years ago. I demonstrated how we can use DBMS_XMLSTORE package to parse XML data. Yesterday, I replied a question from a blog reader about that post. He had problem with running my sample script, I did troubleshoot and find out the problem with his script, and while testing the sample script, I noticed that I can write much better script.

This is my sample XML (employees.xml):

<EMPLOYEES>
<EMPLOYEE>
<NO>1</NO>
<NAME>Gokhan Atil</NAME>
</EMPLOYEE>
<EMPLOYEE>
<NO>2</NO>
<NAME>Ned Flanders</NAME>
</EMPLOYEE>
<EMPLOYEE>
<NO>3</NO>
<NAME>Agnes Skinner</NAME>
</EMPLOYEE>
<EMPLOYEE>
<NO>4</NO>
<NAME>Milhouse Van Houten</NAME>
</EMPLOYEE>
</EMPLOYEES>

I created a table to load the data and a directory link so we can access the file:

CREATE TABLE empfromxml ( no NUMBER, name VARCHAR2(50 ));
CREATE DIRECTORY xmltest AS '/oracle/xmltest';

Instead of using DBMS_XMLSTORE, I decided to use XMLType functions ExtractValue and XMLSequence. So I modified my old sample script and wrote this one:

DECLARE
xml_file BFILE;
xml_data CLOB;
BEGIN
xml_file := BFILENAME ('XMLTEST', 'employees.xml');
DBMS_LOB.createtemporary (xml_data, TRUE, DBMS_LOB.SESSION);
DBMS_LOB.fileopen (xml_file, DBMS_LOB.file_readonly);
DBMS_LOB.loadfromfile (xml_data, xml_file, DBMS_LOB.getlength(xml_file));
DBMS_LOB.fileclose (xml_file);

INSERT INTO EMPFROMXML (no, name)
    SELECT ExtractValue(Value(x),'//NO') as no,
           ExtractValue(Value(x),'//NAME') as name
    FROM   TABLE(XMLSequence(Extract(XMLType(xml_data),'/EMPLOYEES/EMPLOYEE'))) x;

DBMS_OUTPUT.PUT_LINE( SQL%ROWCOUNT || ' rows inserted.' );
DBMS_LOB.freetemporary (xml_data);
COMMIT;
END;
/

You can compare it with my previous one. As you can see, I removed DBMS_XMLSTORE functions and write a simple SQL to fetch data from a CLOB which contains XML data. The main process is just an INSERT query but there are still some ugly stuff because I need to deal with reading file to the CLOB variable.

Then I realized that I could just remove all the CLOB stuff. In fact, a simple SQL can handle all the task:

INSERT INTO EMPFROMXML (no, name)
    SELECT ExtractValue(Value(x),'//NO') as no,
           ExtractValue(Value(x),'//NAME') as name
    FROM   TABLE(XMLSequence(Extract(XMLType(bfilename('XMLTEST', 'employees.xml'), 
    nls_charset_id('UTF8') ),'/EMPLOYEES/EMPLOYEE'))) x;

This code will read from employees.xml file in XMLTEST directory, parse the data (the rowtag is EMPLOYEE, the fields are NO and NAME) and insert it into the EMPFROMXML table.

xmltype

Very clean and simple!


Viewing all articles
Browse latest Browse all 108

Trending Articles