Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Import XML do Oracle za pomocą SQL Developer

Próbujesz zaktualizować dwie kolumny z podzapytania, ale Twoja składnia jest nieprawidłowa; powinno być bardziej jak:

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

W twoim przypadku coś takiego, zakładając, że wstawiasz i aktualizujesz tę samą tabelę i przekazujesz (zmodyfikowany) surowy XML jako zmienną SQL*Plus do moich testów:

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)

Następnie aktualizacja może wyglądać następująco:

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)

Jeśli oczywiście zakłada to również jedną stację na aplikację, w przeciwnym razie będziesz potrzebować wielu połączonych tabel, aby utrzymać relacje, jak sądzę; i tylko jedna aplikacja lub twoja aktualizacja musiałyby być w jakiś sposób skorelowane. Ale wtedy aktualizacja wydaje się bezcelowa, możesz to wszystko zrobić na wstawce:

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;

... (co działa tylko w relacjach jeden-do-jednego), więc wyraźnie brakuje mi czegoś na zdjęciu.

Na podstawie Twoich komentarzy, że masz relacje jeden-do-wielu i wstawiasz wszystko do jednej tabeli (!?), możesz to zrobić:

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
/

Zszedłem o dodatkowy poziom do nadajnika i możesz po prostu powtórzyć wzór, aby dodać więcej, za każdym razem przekazując odpowiedni węzeł w dół. Zewnętrzne łączy (+) pozwoli na niektóre rzeczy nieistniejące, np. jeśli masz nadajnik, który nie otrzymał jeszcze częstotliwości, lub cokolwiek innego - otrzymasz null w odpowiednich kolumnach.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nie można otworzyć lib '/usr/lib/oracle/11.2/client64/lib/libsqora.so.11.1 podczas tworzenia elementu Database Monitor w zabbix

  2. Nie znaleziono danych lub wystąpił błąd wyjątku zbyt wielu wierszy podczas zbiorczego wstawiania rekordów

  3. Scal zakresy dat

  4. JDBC PreparedStatement i parametry (?) w wybranym zapytaniu

  5. Odzyskiwanie dużych danych typu clob za pomocą sqlplus