我确实有以下数据:
<EXDATA>
<FLAG_LIST>
<FLAG>
<INST>APPLE</INST>
<IDENT_LIST>
<IDET NAME="ID_NUMBER" INST="AMOZ">111111111111</IDET>
<IDET NAME="ID_PASSPORT" INST="AMOZ">2222222222222</IDET>
</IDENT_LIST>
<FLAGYN>0</FLAGYN>
<EDATA_LIST_REQ>
<EDATA NAME="NAM">JACKIE</EDATA>
<EDATA NAME="SURNAME" INSTO="AMOZ">JOHN</EDATA>
</EDATA_LIST_REQ>
</FLAG>
</FLAG_LIST>
</EXDATA>
我尝试通过以下方式将数据插入表中:
select x1.ID_NUMBER,X1.ID_PASSPORT,X2.NAM,x2.SURNAME
from xml_tab t
, xmltable(
'/EXDATA/FLAG_LIST/FLAG/IDENT_LIST'
passing t.xml_data
columns ID_NUMBER varchar2(100) path 'IDET[1]/text()',
ID_PASSPORT number path 'IDET[2]/text()'
, EDATA_LIST_REQ xmltype path 'EDATA_LIST_REQ'
) (+) x1
, xmltable(
'/EDATA_LIST_REQ'
passing x1.EDATA_LIST_REQ
columns
NAM VARCHAR2(13) path 'EDATA[1]/text()' ,
SURNAME VARCHAR2(50) path 'EDATA[2]/text()'
) (+) x2
但是没有正确的结果:
ID_NUMBER ID_PASSPORT NAME SURNAME
111111111 222222222222 NULL NULL
请帮助。
答案 0 :(得分:0)
在您的第一个XMLTable调用中,您正在寻找EDATA_LIST_REQ
传递给第二个XMLTable调用。但是您正在/EXDATA/FLAG_LIST/FLAG/IDENT_LIST
下寻找它。它不是IDENT_LIST
的子级,而是同级。因此,您可以使用'./../EDATA_LIST_REQ'
更改要遍历的路径:
select x1.ID_NUMBER,X1.ID_PASSPORT,X2.NAM,x2.SURNAME
from xml_tab t
, xmltable(
'/EXDATA/FLAG_LIST/FLAG/IDENT_LIST'
passing t.xml_data
columns ID_NUMBER varchar2(100) path 'IDET[1]/text()',
ID_PASSPORT number path 'IDET[2]/text()'
, EDATA_LIST_REQ xmltype path './../EDATA_LIST_REQ'
) (+) x1
, xmltable(
'/EDATA_LIST_REQ'
passing x1.EDATA_LIST_REQ
columns
NAM VARCHAR2(13) path 'EDATA[1]/text()' ,
SURNAME VARCHAR2(50) path 'EDATA[2]/text()'
) (+) x2
或离开该路径并更改其他两个和主要的XPath:
select x1.ID_NUMBER,X1.ID_PASSPORT,X2.NAM,x2.SURNAME
from xml_tab t
, xmltable(
'/EXDATA/FLAG_LIST/FLAG'
passing t.xml_data
columns ID_NUMBER varchar2(100) path 'IDENT_LIST/IDET[1]/text()',
ID_PASSPORT number path 'IDENT_LIST/IDET[2]/text()'
, EDATA_LIST_REQ xmltype path 'EDATA_LIST_REQ'
) (+) x1
, xmltable(
'/EDATA_LIST_REQ'
passing x1.EDATA_LIST_REQ
columns
NAM VARCHAR2(13) path 'EDATA[1]/text()' ,
SURNAME VARCHAR2(50) path 'EDATA[2]/text()'
) (+) x2
但是您不需要外部联接,并且在使用XMLTable时不需要显式引用/text()
;但更麻烦的是您使用[1]
和[2]
来引用列表中的特定节点。这似乎是在对数据结构进行假设,这些假设可能无法保证始终是正确的。有了属性名称,使用属性名称会更安全,更清晰。所以我可能会做更多类似的事情:
select x1.id_number, x1.id_passport, x2.nam, x2.surname
from xml_tab t
cross join xmltable (
'/EXDATA/FLAG_LIST/FLAG'
passing t.xml_data
columns id_number varchar2(100) path 'IDENT_LIST/IDET[@NAME="ID_NUMBER"]',
id_passport number path 'IDENT_LIST/IDET[@NAME="ID_PASSPORT"]',
edata_list_req xmltype path 'EDATA_LIST_REQ'
) x1
cross join xmltable (
'/EDATA_LIST_REQ'
passing x1.edata_list_req
columns nam varchar2(13) path 'EDATA[@NAME="NAM"]',
surname varchar2(50) path 'EDATA[@NAME="SURNAME"]'
) x2
第二个XPath甚至只是'.'
,尽管重复/EDATA_LIST_REQ
并没有什么坏处。
尽管您可能要检查这些数据类型-id_number
实际上是数字还是字母数字? varchar2
列的长度是否合理?等等