Oracle
 sql >> Database >  >> RDS >> Oracle

Importazione XML in Oracle con SQL Developer

Stai cercando di aggiornare due colonne da una sottoquery, ma la tua sintassi è sbagliata; dovrebbe essere più simile a:

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

Nel tuo caso qualcosa del genere, supponendo che tu stia inserendo e aggiornando la stessa tabella e passando l'XML grezzo (modificato) come una var SQL*Plus per i miei test:

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)

Quindi l'aggiornamento potrebbe essere:

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)

Se ovviamente questo presuppone anche una stazione per applicazione, altrimenti avrai bisogno di più tabelle unite per mantenere le relazioni suppongo; e solo un'applicazione o il tuo aggiornamento dovrebbe essere correlato in qualche modo. Ma poi l'aggiornamento sembra inutile, potresti fare tutto su inserto:

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;

... (che funziona solo con relazioni uno-a-uno) così chiaramente mi manca qualcosa dall'immagine.

Sulla base dei tuoi commenti che hai relazioni uno-a-molti e stai inserendo tutto in una tabella (!?), puoi invece farlo:

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
/

Sono sceso di un livello extra al trasmettitore e puoi semplicemente ripetere lo schema per aggiungerne altro, passando ogni volta il nodo pertinente. Il join esterno (+) consentirà alcune cose non esistenti, ad es. se hai un trasmettitore a cui non è stata ancora assegnata una frequenza, o qualsiasi altra cosa, otterrai un valore nullo nelle colonne pertinenti.