2013-05-03 69 views
0

我想用SQL開發人員將XML文件導入到Oracle SQL。該XML有一個以上的節點,我的XML結構:用SQL Developer將XML導入到Oracle

<"<"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/>">" 

首先,我創建的表SPECTRAEXCHANGE,比我想用下面的命令:

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; 

等。

而且在更新會話中,我收到了錯誤消息: 00933. 00000 - 「SQL命令未正確結束」

我試過這個更新會話:

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; 

,但不幸的是它不工作... 所以你能幫助我更新的一部分?或者給我其他教程來導入多個節點的XML。 謝謝。 米蘭

+2

該XML是否以任何方式或形式驗證?看起來不像我以前見過的任何XML。 – 2013-05-03 07:08:23

+0

開始和結束標記不是'正常' – user2342549 2013-05-03 08:51:54

回答

1

您試圖更新子查詢中的兩列,但您的語法錯誤;它應該更像:

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) 

如果當然這還假定每個應用程序一個站,否則你會需要多個連接的表來保存我猜的關係;並且只有一個應用程序或您的更新需要以某種方式進行關聯。但隨後的更新似乎毫無意義,你可以做所有的插入:

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; 

...(其中只有一個一對一關係的工作),所以顯然我錯過從圖片上的東西。 (!?)


根據您的意見,你有一個一對多的關係,你的一切插入到一個表,你可以這樣做,而不是:

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 
/

我已經降低了發射機的額外電平,並且您可以重複該模式以添加更多,每次都向下傳遞相關節點。外連接(+)將允許某些不存在的事物,例如,如果你有一個發射器還沒有給出頻率,或者其他什麼 - 你會在相關列中得到一個空值。

+0

謝謝,但我收到錯誤消息:01427. 00000 - 「單行子查詢返回多行」 – user2342549 2013-05-03 10:00:22

+0

@ user2342549 - 顯示的數據或更大有多個應用程序和/或站的樣本?我認爲你需要更清楚你想要實現什麼以及數據如何排列在表格中;將表格模式添加到問題可能會有所幫助。 – 2013-05-03 10:02:07

+0

我想在更新部分中導入更多行,並且插入部分包含更多行。 – user2342549 2013-05-03 10:02:16