XML import to Oracle with SQL Developer

I would like to import an XML file to Oracle SQL with SQL developer. The XML has more than one node, my XML structure:

<"<"SPECTRAEXCHANGE>">"
<"<"APPLICATION>">"
<"<"SV_SV_ID>">"kClong<"<"/SV_SV_ID/>">"
<"<"SS_SS_ID>">"kClong<"<"/SS_SS_ID/>">"
<"<"AP_NAME>">"kCstring (64)<"<"/AP_NAME/>">"
<"<"AP_PRJ_IDENT>">"kCstring (32)<"<"/AP_PRJ_IDENT/>">"
<"<"STATION>">"
<"<"TCS_NAME>">"kCstring (64)<"<"/TCS_NAME/>">"
<"<"TCS_CALL>">"kCstring (256)<"<"/TCS_CALL/>">"
<"<"HORIZONTAL_ELEVATIONS>">"
<"<"HORIZONTAL_ELEVATION>">"
<"<"HE_AZIMUT>">"kCdouble<"<"/HE_AZIMUT/>">"
<"<"HE_ELEVATION>">"kCdouble<"<"/HE_ELEVATION/>">"
<"<"/HORIZONTAL_ELEVATION/>">"
<"<"/HORIZONTAL_ELEVATIONS/>">"
<"<"TRANSMITTER>">"
<"<"EQP_EQUIP_NAME>">"kCstring (128)<"<"/EQP_EQUIP_NAME/>">"
<"<"EQP_EQUIP_TYPE>">"kCstring (16)<"<"/EQP_EQUIP_TYPE/>">"
<"<"FREQUENCY>">"
<"<"EFL_FREQ>">"kCdouble<"<"/EFL_FREQ/>">"
<"<"COORDINATED_FREQUENCY>">"
<"<"COF_DAT>">"kWrDate<"<"/COF_DAT/>">"
<"<"/COORDINATED_FREQUENCY/>">"
<"<"/FREQUENCY/>">"
<"<"/TRANSMITTER/>">"
<"<"/STATION/>">"
<"<"/APPLICATION/>">"
<"<"/SPECTRAEXCHANGE/>">" 

First I created the table SPECTRAEXCHANGE and than I want to use the following commands:

INSERT INTO TABLENAME(SV_SV_ID,
SS_SS_ID,
AP_NAME,
AP_PRJ_IDENT )
WITH t AS (SELECT xmltype(bfilename('TEST_DIR','yourXMLFileName.xml'), nls_charset_id('WE8ISO8859P1')) xmlcol FROM dual)
SELECT
extractValue(value(x),'/APPLICATION/SV_SV_ID') SV_SV_ID /* value will be kClong */
,extractValue(value(x),'/APPLICATION/SS_SS_ID') SS_SS_ID /* value will be kClong*/
,extractValue(value(x),'APPLICATION/AP_NAME') AP_NAME /* value will be kCstring (64)*/
,extractValue(value(x),'APPLICATION/AP_PRJ_IDENT') AP_PRJ_IDENT
FROM t,TABLE(XMLSequence(extract(t.xmlcol,'/SPECTRAEXCHANGE/APPLICATION'))) x;


UPDATE SPECTRAEXCHANGE SET TCS_NAME = extractValue(value(x),'/APPLICATION/STATION/TCS_NAME'),
TCS_CALL = extractValue(value(x),'/APPLICATION/STATION/TCS_CALL')
WITH t AS (SELECT xmltype(bfilename('TEST_DIR','yourXMLFileName.xml'), nls_charset_id('WE8ISO8859P1')) xmlcol FROM dual)
FROM t,TABLE(XMLSequence(extract(t.xmlcol,'/SPECTRAEXCHANGE/APPLICATION/STATION'))) x;

etc..

And in UPDATE session I got error message: 00933. 00000 - "SQL command not properly ended"

And I tried this for UPDATE session:

UPDATE SPECTRAEXCHANGE SET
TCS_NAME = x.TCS_NAME,
TCS_CALL = x.TCS_CALL
WITH t AS (SELECT xmltype(bfilename('TEST_DIR','yourXMLFileName.xml'), nls_charset_id('WE8ISO8859P1')) xmlcol FROM dual)
SELECT
extractValue(value(x),'APPLICATION/STATION/TCS_NAME') TCS_NAME
,extractValue(value(x),'APPLICATION/STATION/TCS_CALL') TCS_CALL
FROM t,TABLE(XMLSequence(extract(t.xmlcol,'/SPECTRAEXCHANGE/APPLICATION/STATION'))) x; 

but unfortunatly it doesn't work... so can you help me with update part? or give me other tutorial to import xml with more than one node. thanks. Milan

Answers


You're trying to update two columns from a subquery, but your syntax is wrong; it should be more like:

update tablename set (col1 = val1, col2 = val2)
select (val1, val 2 from ...)

In your case something like this, assuming you're inserting and updating the same table, and passing the (modified) raw XML as an SQL*Plus var for my testing:

create table spectraexchange(sv_sv_id varchar2(15), ss_ss_id varchar2(15),
    ap_name varchar2(15), ap_prj_ident varchar2(15),
    tcs_name varchar2(15), tcs_call varchar2(15));

Table created.

insert into spectraexchange(sv_sv_id, ss_ss_id, ap_name, ap_prj_ident)
select extractvalue(value(x), 'APPLICATION/SV_SV_ID') sv_sv_id,
    extractvalue(value(x), 'APPLICATION/SS_SS_ID') ss_ss_id,
    extractvalue(value(x), 'APPLICATION/AP_NAME') ap_name,
    extractvalue(value(x), 'APPLICATION/AP_PRJ_IDENT') ap_prj_ident
from (
    select xmltype(:raw_xml) xmlcol from dual
) t
cross join table(XMLSequence(extract(t.xmlcol,
    '/SPECTRAEXCHANGE/APPLICATION'))) x;

1 row created.

select * from spectraexchange;

SV_SV_ID        SS_SS_ID        AP_NAME         AP_PRJ_IDENT    TCS_NAME        TCS_CALL
--------------- --------------- --------------- --------------- --------------- ---------------
kClong          kClong          kCstring (64)   kCstring (32)

Then the update could be:

update spectraexchange
set (tcs_name, tcs_call) = (
    select extractvalue(value(x), 'STATION/TCS_NAME'),
        extractvalue(value(x), 'STATION/TCS_CALL')
    from (
        select xmltype(:raw_xml) xmlcol from dual
    ) t
    cross join table(XMLSequence(extract(t.xmlcol,
        '/SPECTRAEXCHANGE/APPLICATION/STATION'))) x
);

1 row updated.

select * from spectraexchange;

SV_SV_ID        SS_SS_ID        AP_NAME         AP_PRJ_IDENT    TCS_NAME        TCS_CALL
--------------- --------------- --------------- --------------- --------------- ---------------
kClong          kClong          kCstring (64)   kCstring (32)   kCstring (64)   kCstring (256)

If course this also assumes one station per application, otherwise you'll need multiple joined tables to hold the relationships I guess; and only one application or your update would need to be correlated somehow. But then the update seems pointless, you could do it all on insert:

insert into spectraexchange(sv_sv_id, ss_ss_id, ap_name, ap_prj_ident,
    tcs_name, tcs_call)
select extractvalue(value(x), 'APPLICATION/SV_SV_ID') sv_sv_id,
    extractvalue(value(x), 'APPLICATION/SS_SS_ID') ss_ss_id,
    extractvalue(value(x), 'APPLICATION/AP_NAME') ap_name,
    extractvalue(value(x), 'APPLICATION/AP_PRJ_IDENT') ap_prj_ident,
    extractvalue(value(x), 'APPLICATION/STATION/TCS_NAME') tcs_name,
    extractvalue(value(x), 'APPLICATION/STATION/TCS_CALL') tcs_call
from (
    select xmltype(:raw_xml) xmlcol from dual
) t
cross join table(XMLSequence(extract(t.xmlcol,
    '/SPECTRAEXCHANGE/APPLICATION'))) x;

... (which only works with one-to-one relationships) so clearly I'm missing something from the picture.


Based on your comments that you have one-to-many relationships and you're inserting everything into one table (!?), you can do this instead:

insert into spectra exchange ( ... columns ... )
select a.sv_sv_id, a.ss_ss_id, a.ap_name, a.ap_prj_ident,
    s.tcs_name, s.tcs_call,
    t.eqp_equip_name, t.eqp_equip_type
from (select xmltype(:raw_xml) xmlcol from dual) r
cross join xmltable('/SPECTRAEXCHANGE/APPLICATION' passing r.xmlcol
        columns sv_sv_id varchar2(15) path 'SV_SV_ID',
            ss_ss_id varchar2(15) path 'SS_SS_ID',
            ap_name varchar2(15) path 'AP_NAME',
            ap_prj_ident varchar2(15) path 'AP_PRJ_IDENT',
            stations xmltype path 'STATION'
    ) (+) a
cross join xmltable('/STATION' passing a.stations
        columns tcs_name varchar2(15) path 'TCS_NAME',
            tcs_call varchar2(15) path 'TCS_CALL',
            transmitter xmltype path 'TRANSMITTER'
    ) (+) s
cross join xmltable('/TRANSMITTER' passing s.transmitter
        columns eqp_equip_name varchar2(15) path 'EQP_EQUIP_NAME',
            eqp_equip_type varchar2(15) path 'EQP_EQUIP_TYPE',
            frequency xmltype path 'FREQUENCY'
    ) (+) t
/

I've gone down an extra level to transmitter, and you can just repeat the pattern to add more, passing the relevant node down each time. The outer joins (+) will allow for some things not existing, e.g. if you have a transmitter that hasn't been given a frequency yet, or whatever - you'll get a null in the relevant columns.


Need Your Help

Trying to remove nan from csv file in python pandas

python csv pandas nan phone-number

I am trying to remove nan values from a final csv file, which will source data for digital signage.

QML: wait until animations finished

qt qml

I am trying to make visible animations sequential. I have a javascript function, which call myModel.move() two times. I have a GridView to show myModel and I have "Behavior on x" animation, thus I ...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.