<detailedOutput>
<entity>
<entityLabel>Policy Holder 1</entityLabel>
<entityName>PHN.1</entityName>
<entityType>Policy Holder Name</entityType>
<fact>
<name>fired</name>
<nameContents>Y</nameContents>
<messageCode>M003</messageCode>
<reported>Y</reported>
<uniqueID>C_9_3_1</uniqueID>
<instanceID>1.1</instanceID>
</fact>
<fact>
<name>fired</name>
<nameContents>Y</nameContents>
<messageCode>M010</messageCode>
<reported>Y</reported>
<uniqueID>C_4_3_1</uniqueID>
<instanceID>1.1</instanceID>
</fact>
</entity>
<entity>
<entityLabel>property</entityLabel>
<entityName>PROP.1</entityName>
<entityType>Property</entityType>
<fact>
<name>propertyAddress</name>
<nameContents>1280 Somewhere Street, San Diego, WA 98312</nameContents>
</fact>
<fact>
<name>inqZipCode</name>
<nameContents>98312</nameContents>
</fact>
</detailedOutput>
我有这样的XML,我需要读取所有值并将其存储在SQL中的表中。我跟随我的代码:
for rec_facts in (
select EXTRACTVALUE(VALUE(TAB),'/entity/entityLabel/text()') as entity_label
,EXTRACTVALUE(VALUE(TAB),'/entity/entityName/text()') as entity_name
,EXTRACTVALUE(VALUE(TAB),'/entity/entityType/text()') as entity_type
FROM TABLE(XMLSEQUENCE(EXTRACT(SYS.XMLTYPE(v_xmltype),'/creditBureau/product/custom/riskVerificationPlatform/detailedOutput/entity'))) TAB
union all
select null, null, null from dual where not exists (select 1 from table(xmlsequence(extract(sys.xmltype(v_xmltype),'/creditBureau/product/custom/riskVerificationPlatform/detailedOutput/entity')))TAB1)
)
loop
for recout in (
select EXTRACTVALUE(VALUE(TAB2),'/fact/name/text()') as fact_name
,EXTRACTVALUE(VALUE(TAB2),'/fact/nameContents/text()') as fact_nameContents
,EXTRACTVALUE(VALUE(TAB2),'/fact/messageCode/text()') as fact_messageCode
,EXTRACTVALUE(VALUE(TAB2),'/fact/reported/text()') as fact_reported
,EXTRACTVALUE(VALUE(TAB2),'/fact/uniqueID/text()') as fact_uniqueID
,EXTRACTVALUE(VALUE(TAB2),'/fact/instanceID/text()') as fact_instanceID
TABLE(XMLSEQUENCE(EXTRACT(SYS.XMLTYPE(v_xmltype),'/creditBureau/product/custom/riskVerificationPlatform/message'))) TAB2
union all
select null, null, null, null, null, null from dual where not exists (select 1 from table(xmlsequence(extract(sys.xmltype(v_xmltype),'/creditBureau/product/custom/riskVerificationPlatform/message')))TAB2)
)
loop
insert into TUNA_FACTS
(TUNA_FACTS
,TUNA_WEB_REQUEST_RESPONSE
,ENTITY_LABEL
,ENTITY_NAME
,ENTITY_TYPE
,FACT_NAME
,FACT_NAMECONTENTS
,FACT_MESSAGECODE
,FACT_REPORTED
,FACT_UNIQUEID
,FACT_INSTANCEID
,CREATED_ON
,CREATED_BY
,AUDIT_ID
)
values
(seq_TUNA_FACTS.nextval
,v_seq_TUNA_web_req_res
,rec_facts.entity_label
,rec_facts.entity_name
,rec_facts.entity_type
,recout.fact_name
,recout.fact_nameContents
,recout.fact_messageCode
,recout.fact_reported
,recout.fact_uniqueID
,recout.fact_instanceID
,sysdate
,'TUNA'
,user);
end loop;
end loop;
代码运行,但它重复每个entityLabel,entityName和entityType 4次而不是2次。例如,表格应如下所示:
entityLabel entityName entityType FactName
--------------- ---------- ------------------ ---------------
Policy Holder 1 PHN.1 Policy Holder Name fired
Policy Holder 1 PHN.1 Policy Holder Name fired
property PROP.1 Property PropertyAddress
property PROP.1 Property inqZipCode
相反,它创建了一个表格,如:
entityLabel entityName entityType FactName
--------------- ---------- ------------------ ---------------
Policy Holder 1 PHN.1 Policy Holder Name fired
Policy Holder 1 PHN.1 Policy Holder Name fired
Policy Holder 1 PHN.1 Policy Holder Name PropertyAddress
Policy Holder 1 PHN.1 Policy Holder Name inqZipCode
property PROP.1 Property fired
property PROP.1 Property fired
property PROP.1 Property PropertyAddress
property PROP.1 Property inqZipCode
我确信这是一个循环问题,但我无法弄明白。任何帮助,将不胜感激!
答案 0 :(得分:3)
for-loop
构造在这里是多余的。单个选择语句完全符合您的要求
在下面的例子中,我使用了问题中提出的数据:
create table xmldata as
with xmldoc as (
select xmlType('
<detailedOutput>
<entity>
<entityLabel>Policy Holder 1</entityLabel>
<entityName>PHN.1</entityName>
<entityType>Policy Holder Name</entityType>
<fact>
<name>fired</name>
<nameContents>Y</nameContents>
<messageCode>M003</messageCode>
<reported>Y</reported>
<uniqueID>C_9_3_1</uniqueID>
<instanceID>1.1</instanceID>
</fact>
<fact>
<name>fired</name>
<nameContents>Y</nameContents>
<messageCode>M010</messageCode>
<reported>Y</reported>
<uniqueID>C_4_3_1</uniqueID>
<instanceID>1.1</instanceID>
</fact>
</entity>
<entity>
<entityLabel>property</entityLabel>
<entityName>PROP.1</entityName>
<entityType>Property</entityType>
<fact>
<name>propertyAddress</name>
<nameContents>1280 Somewhere Street, San Diego, WA 98312</nameContents>
</fact>
<fact>
<name>inqZipCode</name>
<nameContents>98312</nameContents>
</fact>
</entity>
</detailedOutput>
') xml from dual
)
select xml from xmldoc
/
Table XMLDATA created.
extract()
和xmlSequence
的声明:
select
extractValue (value(e), '/entity/entityLabel') as "entityLabel",
extractValue (value(e), '/entity/entityName') as "entityName",
extractValue (value(e), '/entity/entityType') as "entityType",
extractValue (value(f), '/fact/name') as "factName"
from xmldata x,
table (xmlSequence(extract(xml, '/detailedOutput/entity'))) e,
table (xmlSequence(extract(value(e), '/entity/fact'))) f
/
另请注意,xmlSequence
已deprecated而应使用xmlTable代替:
select e."entityLabel", e."entityName", e."entityType", f."factName"
from xmldata x cross join
xmlTable ('/detailedOutput/entity' passing x.xml columns
"entityLabel" varchar2(32) path '/entity/entityLabel',
"entityName" varchar2(32) path '/entity/entityName',
"entityType" varchar2(32) path '/entity/entityType',
facts xmlType path 'fact'
) e cross join
xmlTable ('fact' passing e.facts columns
"factName" varchar2(32) path '/fact/name'
) f
/
这两个陈述的输出是相同的:
entityLabel entityName entityType factName
---------------- ---------------- ------------------------ ----------------
Policy Holder 1 PHN.1 Policy Holder Name fired
Policy Holder 1 PHN.1 Policy Holder Name fired
property PROP.1 Property propertyAddress
property PROP.1 Property inqZipCode
4 rows selected.
现在PL / SQL块可能看起来很简单:
create view tuna_facts_view as <one of both selects suggested above>;
create table tuna_facts as select * from tuna_facts_view where 1=0;
declare
function insertTunaFacts return integer is
begin
insert into tuna_facts select * from tuna_facts_view;
return sql%rowcount;
end insertTunaFacts;
begin
dbms_output.put_line ('inserted rows '||insertTunaFacts ());
end;
/
PL/SQL procedure successfully completed.
inserted rows 4