我对XML很陌生,我希望在此列出所有相关信息。如果没有,请不要发送负面反馈。如果您告诉我您缺少哪些信息,我将不胜感激。
我无法在Oracle Database 11g上的XML视图中的多个元素上正确运行查询。
我有多个XML文件,结构如下:
<Qualitaetsbericht>
<Organisationseinheiten_Fachabteilungen>
<Organisationseinheiten_Fachabteilung>
<Fachabteilungsschluessel>
<Prozeduren>
<Freiwillig>
<Verpflichtend>
<Prozedur>
<OPS_301>
<Anzahl>
我通常得到以下查询的正确结果:
SELECT id,
d."FA_SCHLUESSEL",d."OPS_301",
CASE WHEN d."ANZAHL" IS NULL THEN '4' ELSE d."ANZAHL" END AS ANZAHL,
d."GLIEDERUNGSNUMMER",d."NAME"
FROM XMLDocs x,
XMLTable(
'/Data'
PASSING XMLQuery(
'for $i in /Qualitaetsbericht./Organisationseinheiten_Fachabteilungen/Organisationseinheit_Fachabteilung/Prozeduren/Verpflichtend/Prozedur
return <Data>
{$i/OPS_301}
{$i/Anzahl}
{$i/../../../Fachabteilungsschluessel/FA_Schluessel}
{$i/../../../Gliederungsnummer}
{$i/../../../Name}
</Data>'
PASSING doc
RETURNING CONTENT
)
COLUMNS FA_Schluessel varchar2(12) path 'FA_Schluessel',
OPS_301 varchar2(12) path 'OPS_301',
Anzahl varchar2(40) path 'Anzahl',
Gliederungsnummer varchar2(10) path 'Gliederungsnummer',
Name varchar2(600) path 'Name'
) d
但是还有一个可能发生的元素
如果在XML中给出了此元素,则上面的查询会遇到动态类型不匹配错误。
我想出了
<Fachabteilungsschluessel>
承担这种结构
<Fachabteilungsschluessel>
<FA_Schluessel>
或
<Fachabteilungsschluessel>
<Sonstiger>
<FA_Sonstiger_Schluessel>
每当
<Fachabteilungsschluessel>
<Sonstiger>
<FA_Sonstiger_Schluessel>
出现在XML文档中我收到错误代码:
ORA-19279: XPTY0004 - XQuery dynamic type mismatch: expected singleton sequence - got multi-item sequence
我希望这是一个容易解决的问题。目前我的想法已经不多了。有人可以帮忙吗? - 提前谢谢。
此处的示例文件:
file
答案 0 :(得分:2)
问题在于重复的节点。在您的第二个Organisationseinheit_Fachabteilung
节点(其中Gliederungsnummer
为2)中,有两个 Fachabteilungsschluessel
个节点,每个节点都有FA_Schluessel
- 0193和0300。
在您的XMLQuery中,您将从Prozedur
个节点开始,然后引用该结构以查找../../../Fachabteilungsschluessel/FA_Schluessel
。在这种情况下,它会找到两个匹配项 - 即预期单个项目的多个项目。
您可以调整XMLQuery的XPath以使用嵌套循环,但它有点乱,难以理解,而且在使用2.5MB文件进行测试时速度也很慢:
...
PASSING XMLQuery(
'for $i in /Qualitaetsbericht/Organisationseinheiten_Fachabteilungen/Organisationseinheit_Fachabteilung
for $j in $i/Prozeduren/Verpflichtend/Prozedur
return <Data>
{$j/OPS_301}
{$j/Anzahl}
{$i/Fachabteilungsschluessel/FA_Schluessel}
{$i/Gliederungsnummer}
{$i/Name}
</Data>'
PASSING doc
RETURNING CONTENT
)
...
虽然你不需要单独的XMLQuery,但XMLTable的XPath可以自己完成所有这些。
您可以使用多个级别的XMLTable:
SELECT xd.id,
x3.fa_schluessel,
x2.ops_301,
CASE WHEN x2.anzahl IS NULL THEN '4' ELSE x2.anzahl END AS anzahl,
x1.gliederungsnummer,
x1.name
FROM XMLDocs xd
CROSS JOIN XMLTable(
'/Qualitaetsbericht/Organisationseinheiten_Fachabteilungen/Organisationseinheit_Fachabteilung'
PASSING doc
COLUMNS gliederungsnummer varchar2(10) path 'Gliederungsnummer',
name varchar2(600) path 'Name',
prozeduren XMLType path 'Prozeduren',
fa_schluessel XMLType path 'Fachabteilungsschluessel/FA_Schluessel'
) x1
CROSS JOIN XMLTable(
'/Prozeduren/Verpflichtend/Prozedur'
PASSING x1.prozeduren
COLUMNS ops_301 varchar2(12) path 'OPS_301',
anzahl varchar2(40) path 'Anzahl'
) x2
CROSS JOIN XMLTable(
'/FA_Schluessel'
PASSING x1.fa_schluessel
COLUMNS fa_schluessel varchar2(12) path '.'
) x3
/
与您的示例数据文件一起获取:
ID FA_SCHLUESSE OPS_301 ANZAHL GLIEDERUNG NAME
---------- ------------ ------------ ---------------------------------------- ---------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
42 0100 1-204.2 4 1 Notfallmedizin
42 0100 1-207.0 5 1 Notfallmedizin
42 0100 1-208.3 4 1 Notfallmedizin
42 0100 1-208.6 4 1 Notfallmedizin
42 0100 1-266.0 4 1 Notfallmedizin
42 0100 1-610.2 4 1 Notfallmedizin
42 0100 1-844 4 1 Notfallmedizin
42 0100 3-052 5 1 Notfallmedizin
42 0100 3-200 67 1 Notfallmedizin
...
第一个XMLTable直接在Organisationseinheit_Fachabteilun
节点下获取数据,并且还将每个节点的子Prozeduren
和'Fachabteilungsschluessel / FA_Schluessel`片段作为单独的XMLTypes获取,这些XMLType可以具有多个节点。然后将这些片段传递给第二个和第三个XMLTables,它们提取较低级别的数据。
使用此模型,可以有多个父节点,每个节点都有多个子节点。
如果你有另一个repeatng节点,你可以将其作为另一个XMLType片段提取,并添加第四个XMLTable:
...
COLUMNS gliederungsnummer varchar2(10) path 'Gliederungsnummer',
name varchar2(600) path 'Name',
prozeduren XMLType path 'Prozeduren',
fa_schluessel XMLType path 'Fachabteilungsschluessel/FA_Schluessel',
fa_sonstiger_schluessel XMLType
path 'Fachabteilungsschluessel/Sonstiger/FA_Sonstiger_Schluessel'
) x1
...
CROSS JOIN XMLTable(
'/FA_Sonstiger_Schluessel'
PASSING x1.fa_sonstiger_schluessel
COLUMNS fa_sonstiger_schluessel varchar2(12) path '.'
) x4
...然后可以在主选择列表中使用x4.fa_sonstiger_schluessel
。
当您添加更多交叉联接时,性能可能会受到影响。