サブクエリから2つの列を更新しようとしていますが、構文が間違っています。次のようになります:
update tablename set (col1 = val1, col2 = val2)
select (val1, val 2 from ...)
あなたの場合、同じテーブルを挿入して更新し、(変更された)生のXMLをテスト用のSQL * Plus変数として渡すと仮定すると、次のようになります。
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)
その場合、更新は次のようになります。
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)
もちろん、これもアプリケーションごとに1つのステーションを想定している場合、そうでない場合は、私が推測する関係を保持するために複数の結合テーブルが必要になります。そして、1つのアプリケーションまたは更新だけを何らかの方法で相互に関連付ける必要があります。しかし、更新は無意味に思えます。すべて挿入時に実行できます:
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;
...(これは1対1の関係でのみ機能します)ので、明らかに私は写真から何かが欠けています。
1対多の関係があり、すべてを1つのテーブル(!?)に挿入しているというコメントに基づいて、代わりにこれを行うことができます:
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
/
送信機にさらにレベルを下げました。パターンを繰り返してさらに追加し、毎回関連するノードを渡すことができます。外部結合(+)
存在しないものを考慮に入れます。まだ周波数が与えられていない送信機などがある場合は、関連する列にnullが表示されます。