[英]Oracle XMLTYPE extract based on value and condition
SELECT * FROM v$version;
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
PL/SQL Release 12.1.0.2.0 - Production
"CORE 12.1.0.2.0 Production"
TNS for Linux: Version 12.1.0.2.0 - Production
NLSRTL Version 12.1.0.2.0 - Production
我有 XML 的示例查詢,如下所示:
with t(xml) as
(
select xmltype(
'<SSO_XML
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
TimeStamp="2020-08-05T21:57:23Z"
Target="Production"
Version="1.0"
TransactionIdentifier="PLAN_A"
SequenceNmbr="123456"
xmlns="http://www.w3.org/2001/XMLSchema">
<PlanCode PlanCodeCode="CHOICE">
<S_DAYS PCODE="P123">
<STUDENT>
<DIVISION Amount="150.05" Code="Flat" S_CODE="1" />
<DIVISION Amount="250.05" Code="Flat" S_CODE="2" />
</STUDENT>
</S_DAYS>
<S_DAYS PCODE="P1234">
<STUDENT>
<DIVISION Amount="150.05" Code="Flat" S_CODE="1" />
<DIVISION Amount="250.05" Code="Flat" S_CODE="2" />
</STUDENT>
</S_DAYS>
<S_DAYS PCODE="Child1">
<AdditonalFare>
<AdditonalFareAmount Amount="100"/>
</AdditonalFare>
</S_DAYS>
<S_DAYS PCODE="Child2">
<AdditonalFare>
<AdditonalFareAmount Amount="130"/>
</AdditonalFare>
</S_DAYS>
</PlanCode>
</SSO_XML>')
from dual
)
select h.PlanCodeCode
,b.*
from t
cross join
xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'/SSO_XML'
passing t.xml
columns PlanCodeCode varchar2(100) path './PlanCode/@PlanCodeCode',
attributes xmltype path './PlanCode'
) h
left join xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'PlanCode/S_DAYS/STUDENT/DIVISION'
passing h.attributes
columns node_level for ordinality
, amount number path '@Amount'
, pcode varchar2(10) path './../../@PCODE'
, child1_amount number path './../../@Amount[1]' --->Child1
, child2_amount number path './../../@Amount[2]' --->Child2
) b on 1=1;
XML 預計會有 S_DAYS 節點和 STUDENT -> DIVISION,我們從 XML 獲取金額值。
有可選節點 S_DAYS 與 S_DAYS 與 PCODE="Child1" 或 PCODE="Child2"
當 Child1 或 Child2 的節點 PCODE 存在時,我們必須自己申請現有的行。
實際結果:
預期結果:
任何幫助都感激不盡。 謝謝。
您可以回到學生s_days
節點的兄弟節點:
select h.PlanCodeCode, b.amount, b.pcode, b.child1_amount, b.child2_amount
from t
cross join
xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'/SSO_XML'
passing t.xml
columns PlanCodeCode varchar2(100) path './PlanCode/@PlanCodeCode',
attributes xmltype path './PlanCode'
) h
left join xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'PlanCode/S_DAYS/STUDENT/DIVISION'
passing h.attributes
columns node_level for ordinality
, amount number path '@Amount'
, pcode varchar2(10) path './../../@PCODE'
, child1_amount number path './../../../S_DAYS[@PCODE="Child1"]/AdditonalFare/AdditonalFareAmount/@Amount'
, child2_amount number path './../../../S_DAYS[@PCODE="Child2"]/AdditonalFare/AdditonalFareAmount/@Amount'
) b on 1=1;
或者,您可以從第一個 XMLTable 中獲取孩子,如果即使沒有學生節點也總是想查看它們:
select h.PlanCodeCode, b.amount, b.pcode, h.child1_amount, h.child2_amount
from t
cross join
xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'/SSO_XML'
passing t.xml
columns PlanCodeCode varchar2(100) path './PlanCode/@PlanCodeCode',
attributes xmltype path './PlanCode',
child1_amount number path './PlanCode/S_DAYS[@PCODE="Child1"]/AdditonalFare/AdditonalFareAmount/@Amount',
child2_amount number path './PlanCode/S_DAYS[@PCODE="Child2"]/AdditonalFare/AdditonalFareAmount/@Amount'
) h
left join xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'PlanCode/S_DAYS/STUDENT/DIVISION'
passing h.attributes
columns node_level for ordinality
, amount number path '@Amount'
, pcode varchar2(10) path './../../@PCODE'
) b on 1=1;
順便說一句,當您在 12c 上時,您可以使用cross apply
和outer apply
- 后者而不是on 1=1
條件下使用 dummy 進行外部連接。
select h.PlanCodeCode, b.amount, b.pcode, h.child1_amount, h.child2_amount
from t
cross apply
xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'/SSO_XML'
passing t.xml
columns PlanCodeCode varchar2(100) path './PlanCode/@PlanCodeCode',
attributes xmltype path './PlanCode',
child1_amount number path './PlanCode/S_DAYS[@PCODE="Child1"]/AdditonalFare/AdditonalFareAmount/@Amount',
child2_amount number path './PlanCode/S_DAYS[@PCODE="Child2"]/AdditonalFare/AdditonalFareAmount/@Amount'
) h
outer apply xmltable(xmlnamespaces(default 'http://www.w3.org/2001/XMLSchema'),
'PlanCode/S_DAYS/STUDENT/DIVISION'
passing h.attributes
columns node_level for ordinality
, amount number path '@Amount'
, pcode varchar2(10) path './../../@PCODE'
) b;
其中任何一個都與您的樣本數據得到相同的結果:
PLANCODECODE | AMOUNT | PCODE | CHILD1_AMOUNT | CHILD2_AMOUNT
:----------- | -----: | :---- | ------------: | ------------:
CHOICE | 150.05 | P123 | 100 | 130
CHOICE | 250.05 | P123 | 100 | 130
CHOICE | 150.05 | P1234 | 100 | 130
CHOICE | 250.05 | P1234 | 100 | 130
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.