问题描述
我有一个问题,是关于从XML文件开始将3个表放在关系中的代码。
这3个表分别是组织、出版和事实表,使它们相互关系。
表下的结构如下:
我使用的代码是:
插入到WOS_DM_PURLICA中,使用触发器和WOS_DM_PURLICA_id_seq序列插入n行,主键为CD_PURL_ID。类似地,在WOS_DM_NOMISING中插入时,使用触发器和WOS_DM_OMBSING_id序列正好插入了n行,主键为CD_ORG_ID。在两个插入操作运行之后,对于介于1和n之间的i ,我希望使用前面两个插入语句中的第i个键的主键,将一行插入FT_ . . . . . . . . . . . . . . . . . . . . . . . . . .
问题是,对于这个代码,我在FT表中只得到了最终的值,但我需要所有的关系。我已经尝试使用INSERTALL语句,但它似乎不能将SELECT作为值使用。
请考虑到循环只是一个尝试,但它不工作,因为我需要。
这3个表分别是组织、出版和事实表,使它们相互关系。
表下的结构如下:
PUBLICATION ------------ CD_PUB (primary key, progressive number automatically generated when a new record has been inserted, thus the value is not taken from the XML file) CD_REC ORGANISATION ------------ CD_ORG (primary key, progressive number automatically generated when a new record has been inserted, thus the value is not taken from the XML file) FT_PUB_ORG ------------ CD_FT (primary key, progressive number automatically generated when a new record has been inserted, thus the value is not taken from the XML file) CD_PUB (I want to insert here the related code of the Publication) CD_ORG (I want to insert here the related code of the Organisation)
我使用的代码是:
BEGIN
FOR i IN 1..10 LOOP
INSERT INTO WOS_DM_PUBLICATION (
CD_UID
, DT_COVERDATE
, FL_HAS_ABSTRACT
, QT_ISSUE
, DT_PUBMONTH
, CD_PUBTYPE
, DT_PUBYEAR
, DT_SORTDATE
, QT_VOL
, CD_PAGE_BEGIN
, CD_PAGE_END
, CD_PAGE
, QT_PAGE_COUNT
, QT_TITLE_COUNT
, LB_TITLE_SOURCE
, LB_TITLE_SERIES
, LB_TITLE_SOURCE_ABBREV
, LB_TITLE_ABBREV_ISO
, LB_TITLE_ABBREV_11
, LB_TITLE_ABBREV_29
, LB_TITLE_ITEM
, LB_TITLE_BOOK_SERIES
, CD_ACCESSION_NO
, CD_LANG_TYPE
, CD_LANG_NORM
, CD_IDS
, FL_IDS_AVAIL
, CD_BIB_ID
, CD_BIB_PAGECOUNT
)
select
RecUid.cd_uid
, PubInfo.*
, Titles.*
, Title.*
, Acc_no.*
, Lang.*
, Lang2.*
, Items.*
from testtable2 t
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'records/REC'
passing t.xml_file
columns
CD_UID varchar2(200) path 'UID',
names xmltype path 'static_data/summary',
identifi xmltype path 'dynamic_data/cluster_related',
lang xmltype path 'static_data/fullrecord_metadata',
item xmltype path 'static_data/item'
) RecUid
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'summary/pub_info'
passing RecUid.names
columns
DT_COVERDATE varchar2(20) path '@coverdate',
FL_HAS_ABSTRACT varchar2(20) path '@has_abstract',
QT_ISSUE varchar2(20) path '@issue',
DT_PUBMONTH varchar2(20) path '@pubmonth',
CD_PUBTYPE varchar2(20) path '@pubtype',
DT_PUBYEAR varchar2(20) path '@pubyear',
DT_SORTDATE varchar2(20) path '@sortdate',
QT_VOL varchar2(20) path '@vol',
CD_PAGE_BEGIN varchar2(20) path 'page/@begin',
CD_PAGE_END varchar2(20) path 'page/@end',
CD_PAGE varchar2(20) path 'page',
CD_PAGE_COUNT varchar2(20) path 'page/@page_count'
) PubInfo
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'summary/titles'
passing RecUid.names
columns
QT_TITLE_COUNT varchar2(20) path '@count'
) Titles
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'summary/titles'
passing RecUid.names
columns
LB_TITLE_SOURCE varchar2(200) path 'title[@type="source"]',
LB_TITLE_SERIES varchar2(200) path 'title[@type="series"]',
LB_TITLE_SOURCE_ABBREV varchar2(200) path 'title[@type="source_abbrev"]',
LB_TITLE_ABBREV_ISO varchar2(200) path 'title[@type="abbrev_iso"]',
LB_TITLE_ABBREV_11 varchar2(200) path 'title[@type="abbrev_11"]',
LB_TITLE_ABBREV_29 varchar2(200) path 'title[@type="abbrev_29"]',
LB_TITLE_ITEM varchar2(200) path 'title[@type="item"]',
LB_TITLE_BOOK_SERIES varchar2(200) path 'title[@type="book_series"]'
) Title
cross join xmltable( xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'cluster_related/identifiers/identifier[@type="accession_no"]'
passing RecUid.identifi
columns
CD_ACCESSION_NO varchar2(200) path '@value'
) Acc_no
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'fullrecord_metadata/languages/language[@type="primary"]'
passing RecUid.lang
columns
CD_LANG_TYPE varchar2(200) path '.'
--CD_LANG_NORM varchar2(200) path 'normalized_languages/language'
) Lang
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'fullrecord_metadata/normalized_languages/language[@type="primary"]'
passing RecUid.lang
columns
CD_LANG_NORM varchar2(200) path '.'
) Lang2
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'item'
passing RecUid.item
columns
CD_IDS VARCHAR(200) path 'ids',
FL_IDS_AVAIL VARCHAR(2) path 'ids/@avail',
CD_BIB_ID VARCHAR(50) path 'bib_id',
CD_BIB_PAGECOUNT VARCHAR(25) path 'bib_pagecount'
) Items ;
INSERT INTO WOS_DM_ORGANISATION (
LB_LEGAL_NAME
, CD_ADD_NO
, LB_FULL_ADDRESS
, CD_CITY
, CD_STATE
, CD_COUNTRY_NAME
-- , CD_POSTAL_CODE
, CD_ZIP_LOCATION
, FL_PARENT
)
select
Organis.*
, 'Y' FL_PARENT
from testtable2 t
cross join xmltable(xmlnamespaces(default 'xxxxxxxxxxxxxxxx'),
'records/REC/static_data/fullrecord_metadata/addresses/address_name'
passing t.xml_file
columns
LB_LEGAL_NAME varchar2(200) path 'address_spec/organizations/organization',
CD_ADD_NO varchar2(200) path 'address_spec/@addr_no',
LB_FULL_ADDRESS varchar2(200) path 'address_spec/full_address',
CD_CITY varchar2(200) path 'address_spec/city',
CD_STATE varchar2(200) path 'address_spec/state',
_COUNTRY_NAME varchar2(200) path 'address_spec/country',
-- CD_POSTAL_CODE varchar2(200) path 'address_spec/zip/.'--,
CD_ZIP_LOCAZION varchar2(200) path 'address_spec/@location'
) Organis ;
INSERT INTO FT_PUB_ORG_TEST
(
CD_PUB_ID ,
CD_ORG_ID )
VALUES
(
WOS_DM_PUBLICATION_id_seq.currval,
WOS_DM_ORGANISATION_id_seq.currval);
x := x + 1;
END LOOP;
COMMIT;
END;
插入到WOS_DM_PURLICA中,使用触发器和WOS_DM_PURLICA_id_seq序列插入n行,主键为CD_PURL_ID。类似地,在WOS_DM_NOMISING中插入时,使用触发器和WOS_DM_OMBSING_id序列正好插入了n行,主键为CD_ORG_ID。在两个插入操作运行之后,对于介于1和n之间的i ,我希望使用前面两个插入语句中的第i个键的主键,将一行插入FT_ . . . . . . . . . . . . . . . . . . . . . . . . . .
问题是,对于这个代码,我在FT表中只得到了最终的值,但我需要所有的关系。我已经尝试使用INSERTALL语句,但它似乎不能将SELECT作为值使用。
请考虑到循环只是一个尝试,但它不工作,因为我需要。
专家解答
如果XML包含的内容足以构成父表的*自然*键,那么我建议将父记录加载到临时表中。例如,
然后从XML中提取,并加载到父GTT中:
然后,在加载这个(或多个)表时,您将连接到父自然键上的这个临时表,以获得前面分配的父序列值。
如果在父XML中没有可以称为自然键的内容,也就是说,您实际上只有XML本身的层次结构,那么解决方法可以是将数据拖入PL/SQL数组并从该数组中工作。从逻辑上讲,这将是:
希望这个能帮上忙
etc
然后从XML中提取,并加载到父GTT中:
PK NATURAL_KEY parent_seq.nextval A parent_seq.nextval B
然后,在加载这个(或多个)表时,您将连接到父自然键上的这个临时表,以获得前面分配的父序列值。
如果在父XML中没有可以称为自然键的内容,也就是说,您实际上只有XML本身的层次结构,那么解决方法可以是将数据拖入PL/SQL数组并从该数组中工作。从逻辑上讲,这将是:
declare
type parent_array is table of parent%rowtype index by pls_integer;
type child_array is table of child%rowtype index by pls_integer;
p parent_array;
c child_array;
begin
for i in ( [your large query producing ALL data, see below] )
loop
if i.is_first_parent = 'Y' then
if p.count > 10000 then
forall x in 1 .. p.count
insert into PARENT values p(x);
forall x in 1 .. c.count
insert into CHILD values c(x);
p.delete;
c.delete;
end if;
p(p.count+1).pk := parent_seq.nextval;
p(p.count).col1 := i.parent_col1;
p(p.count).col2 := i.parent_col2;
end if;
c(c.count+1).pk := child_seq.nextval;
c(c.count).col1 := i.child_col1;
c(c.count).col2 := i.child_col2;
c(c.count).parent_fk := p(p.count).pk; -- the link
end loop;
end;
where your large query is a flattening of the XML, so the data looks like:
PARENT CHILD IS_FIRST_PARENT
parent1 child1 Y
parent1 child2
parent1 child3
parent2 child1 Y
parent2 child2
etc
希望这个能帮上忙
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




