最近在做讀取Oracle數據庫中XML的項目。之前在MSSQL中使用過XPath讀取,非常方便。最近這個Oracle也打算試試。好久不用略有生疏。簡單介紹一下。
讀取前要保存XML,這個很簡單,在Oracle中建立一個CLOB類型的字段即可。更新的SQL如下:
DECLARE
V_xml CLOB :='<xml><name id="1">test1</name><name id="2">test2</name></xml>';
BEGIN
update tablename SET colname=V_xml where ID='1111222454f4913a9df93c718356af8';
END;
存儲XML注意一下特殊字符,在XML只有”<”、”&”等字符是不能直接存入,理論替換兩個即可。所以相對來說XML對特殊字符的處理比較簡單。如下五個是xml預定義的實體引用,替換成第一列的轉義字符即可:
< | < | 小於 |
> | > | 大於 |
& | & | 和號 |
' | ' | 單引號 |
" | " | 引號 |
註釋:在 XML 中,只有字符 "<" 和 "&" 確實是非法的。大於號是合法的,但是用實體引用來代替它是一個好習慣。
替換之後通過XPath讀取,會自動被xml解析器解析。同時XML中還提供了一種<![CDATA[]]>來包含不被xml解析器解析的內容,內層中括號裏面的內容,被解析器當做純文本處理。有幾個問題要注意:
1、CDATA 部分不能包含字符串 "]]>"。
2、不允許嵌套的 CDATA 部分。
3、標記 CDATA 部分結尾的 "]]>" 不能包含空格或折行。
使用轉義字符和<![CDATA[]]>差不多,一般建議較長的文本用<![CDATA[]]>,因爲<![CDATA[]]>的解析速度比較快。較短的字符用轉義即可,cdata寫起來太囉嗦。
言歸正傳,讀取XML是最關鍵的。還是以上面保存的XML爲例。查找在XML中name節點id=1和id=2的值:
SELECT
nvl(extractvalue(xmltype(t.colname),'/xml/name[@id="1"]'),'test3') as name1,
nvl(extractvalue(xmltype(t.colname),'/xml/name[@id="2"]'),'test4') as name2
FROM tablename t
取值的都是基於過程基於XPath語法,XML使用起來和MSSQL基本沒有區別。
另外唯一Oracle和MSSQL區別就是對於null的判讀。MSSQL中null和空,是兩種不同數據;但Oracle中null和空,是一樣的。上面這段中nvl就是判斷是否爲空或null,如果爲空加一個默認值。