2013-05-03 71 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