背景:項目從某數據交換平台獲取XML數據,以Oracle的XMLType格式保存在數據庫字段中,需要建立觸發器、存儲過程,在保存數據時解析XML字段,將數據寫入其他業務表中。
參考資料:Oracle的XMLType操作文檔,地址為https://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb04cre.htm#sthref465
要點總結:
(一)使用SQL語句操作XMLType格式字段的3個主要方法
(1)existsNode(XMLType實例,XPATH表達式)
1.功能:
需要用在where條件中,通過XPATH表達式在傳入的XMLType實例中進行查詢,如果實例中有符合表達式的節點,則函數返回1,否則返回0
2.使用方法:
select * from loginkcn_maritime_manifest where existsNode(xml,'/Root/Header/DocumentName')=1 and id='0272AB47DEDD450FBD06CA07463F245A';
函數中的"xml"為保存XMLType數據的字段名,id為普通varchar2字段,此時existsNode作為where條件的一項來使用,可以篩選出表中的記錄
(2)extract(XMLType實例,XPATH表達式)
1.功能:
需要用在select之后,from之前,用於對查詢出的XMLType字段的值進行進一步提取,從而獲得新的XMLType格式的結果
2.使用方法:
select extract(xml,'/Root/Body/ContainerInfo') from loginkcn_maritime_manifest where existsNode(xml,'/Root/Header/DocumentName')=1 and id='0272AB47DEDD450FBD06CA07463F245A';
在通過existsNode()方法篩選出記錄的基礎上,通過extract方法提取出Root節點下,Body子節點中所有ContainerInfo節點的信息,作為一個新的XMLType類型的結果值
3.注意:
如果在存儲過程中,可以傳入一個XMLType的變量,此時只需要使用select extract('傳入的XMLType變量','XPATH表達式') into '提取出的XMLType變量' from dual;的形式,來將傳入的變量進一步進行提取並保存到新的變量中。
得到的新的XMLType結果可以應用到之后的進一步操作中。
(3)extractValue(XMLType實例,XPATH表達式)
1.功能:extractValue()方法和extract()方法類似,只不過得到數據類型的是節點的具體值,而不是XML節點類型,相當於extract.getStringVal(),通過此方法可以直接得到具體節點值,用來進行下一步操作,如insert到其他表中,此方法是最為常用的方法。
2.使用方法:
select extractValue(xml,'/Root/Body/ContainerInfo/ContainerNumber[1]') from loginkcn_maritime_manifest where existsNode(xml,'/Root/Header/DocumentName')=1 and id='0272AB47DEDD450FBD06CA07463F245A';
3.注意:
此方法只能提取出單個節點的值,不能同時提取多個相同節點的值。
如果要一個節點中有多個重復的子節點,則需要通過XMLSquence轉化先將XMLType數據轉換為Table,然后才能以表的形式獲取所有的子節點值,進而使用到游標循環等操作中(詳細使用見下方)。
(二)對提取出的XML數據進行轉換的2種方法
(1)XMLSequence(XMLType實例)
1.功能:
XMLSequence接收一個XMLType實例(可以用extract函數從數據庫中導出並提取),按照實例中的頂層節點返回一個XMLType數組。配合Oracle的table()函數,可以將XMLType數組按照表的形式進行查詢,然后可以進行count(*)、使用游標循環等操作。
2.使用方法:
select count(*) from table(XMLSequence(extract((select xml from loginkcn_maritime_manifest where id='0272AB47DEDD450FBD06CA07463F245A'),'/Root/Body/ContainerInfo/ContainerNumber')));
3.注意:
XMLSequence需要和table()函數組合使用,效果和XMLTable類似
table函數的應用 表函數可接受查詢語句或游標作為輸入參數,並可輸出多行數據
(2)XMLTable('XPATH表達式' passing 所在表的XMLType列
columns 列名 類型 path XPATH表達式)
1.功能
使用XMLTable可以方便的將XMLType字段轉換為表格形式來進行下一步的操作
此函數將傳入的XMLType列用XPATH表達式過濾后,按照columns定義的列規則,將節點和字段對應起來構成表格
2.使用方法:
select t.id,x.* from loginkcn_maritime_manifest t,xmltable(
'/Root/Body/ContainerInfo/ContainerNumber' passing t.xml
columns container_number varchar2(30) path 'text()'
) x where t.id='0272AB47DEDD450FBD06CA07463F245A';
3.注意:
轉換時要注意XML的格式要符合DTD標准
配合XPATH表達式可以實現更加復雜的篩選邏輯,如按照屬性值進行篩選