Xml Oracle-PL/SQL-INSERT ALL和SELECT as值
我有一个问题,关于从XML文件开始将3个表放入关系的代码 这三个表是组织、出版和事实表,用于将它们联系起来 下表结构:Xml Oracle-PL/SQL-INSERT ALL和SELECT as值,xml,plsql,oracle-sqldeveloper,sql-insert,Xml,Plsql,Oracle Sqldeveloper,Sql Insert,我有一个问题,关于从XML文件开始将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 ORGANISA
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_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',
CD_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;
问题是,对于这段代码,FT表中只有最终值,但我需要所有关系。
我已经尝试过使用INSERT ALL语句,但似乎无法使用SELECT as值
请考虑这个循环只是一个尝试,但它并不像我需要的那样工作。
< p>听起来你想创建一个集合类型CREATE TYPE num_tbl
AS TABLE OF NUMBER;
在PL/SQL块中,需要声明几个集合
DECLARE
l_publication_keys num_tbl;
l_organization_keys num_tbl;
BEGIN
...
FOR j in 1 .. l_publication_keys.count
LOOP
INSERT INTO FT_PUB_ORG_TEST (
CD_PUB_ID ,
CD_ORG_ID )
VALUES (
l_publication_keys(j),
l_organization_keys(j)
);
END LOOP;
然后,INSERT语句将使用RETURNING子句将生成的主键加载到集合中
INSERT INTO WOS_DM_PUBLICATION( <<columns>> )
SELECT <<whatever>>
FROM <<whatever>>
ORDER BY <<something>>
RETURNING cd_pub_id
BULK COLLECT INTO l_publication_keys;
这假设两个集合始终具有完全相同的元素数,并且始终希望匹配每个insert语句中的第j行。这似乎有风险,除非你的数据中有你没有提到的东西
如果要使用cd_uid列关联两个集合中的数据,可能需要为集合创建对象类型
CREATE TYPE uid_obj
AS OBJECT (
cd_uid integer, -- I'm guessing at the data type
key integer
);
CREATE TYPE uid_tbl
AS TABLE OF uid_obj;
然后,您的局部变量将是新类型的集合
DECLARE
l_publication_keys uid_tbl;
l_organization_keys uid_tbl;
BEGIN
您的退货条款将更改为
RETURNING uid_obj( cd_uid, cd_pub_id )
BULK COLLECT INTO l_publication_keys;
最后一次插入可能是
INSERT INTO FT_PUB_ORG_TEST (
CD_PUB_ID ,
CD_ORG_ID )
SELECT p.key,
o.key
FROM TABLE( l_publication_keys ) p
JOIN TABLE( l_organization_keys ) o
ON( p.uid_cd = o.uid_cd );
我相信您是说,insert-into-WOS_-DM_PUBLICATION使用触发器和WOS_-DM_PUBLICATION_-ID_-seq序列插入主键为CD_-PUB_-ID的n行。类似地,insert into WOS_DM_organization使用触发器和WOS_DM_organization_ID_seq序列插入主键为CD_organg_ID的n行。在两个insert运行之后,对于介于1和n之间的i,您希望使用前面两个insert语句的第i个键中的主键将一行插入FT_PUB_ORG_测试。是这样吗?您似乎不太可能真的希望基于位置顺序匹配两个插入操作中的行。当然不能不在你的两个陈述中加入ORDERBY子句。我希望您真的希望通过其他键匹配数据。“但我不知道那把钥匙是什么。”我证实你的猜测。你知道如何更正代码吗?好的。那么,您是说您真的想依靠两个select语句返回的行的任意顺序来确定要连接的行吗?没有你的命令,那是非常危险的。除非出于某种原因,只要每一行都被映射,你就不在乎映射表中的哪些行被映射到彼此?@JustinCave我明白你的意思了。。。我们可以使用CD_UID作为两个表之间的链接。考虑到FT_PUB_ORG_测试表中的CD_UID字段,您知道如何更正我的陈述吗?谢谢您的详细回答。也许我以前误解了,但你说的对,每个酒吧和每个组织都有一行是很奇怪的,事实上我们每个酒吧都有更多的组织。因此,一份出版物只能有一张CD,但可以有更多的组织。你的代码能正常工作吗?@newinIT-第二种使用uid\u obj对象的方法应该能正常工作。假设我已经理解了你的所有要求,这是一个很大的假设。将来,发布一个可复制的测试用例一个简化的问题,包括我们需要复制问题的简化表定义、数据和代码以及期望的输出,这将非常有助于澄清需求。否则,我们就只能猜测了,或者我们不得不在有限的评论中来来回回我真的很感谢你的耐心和解释,我一直在努力让代码工作,但没有成功。。。我有以下错误:PL/SQL:ORA-00933:SQL命令未正确结束-PLS-00103:在预期以下情况之一时遇到符号UID_OBJ::=。@%;符号:=已替换为UID_OBJ以继续。PLS-00103:在预期以下情况之一时遇到大量符号:我真的不明白问题出在哪里。