備注:XML DB是Oracle 9.2中出現的新特性。
1 XML DB安裝
通過DBCA安裝
2 XML DB數據處理
2.1 存儲XML數據到XML表中
2.1.1創建一個有XMLType類型字段的表:
create table xmlcontent (keyvalue varchar2(10) primary key,
xmlvalue xmltype);
2.1.2創建一個XMLType類型表
create table xmltable of xmltype;
2.1.3從XML文件中讀取數據存儲到XML表中
創建Directory指向存放XML文件的路徑:
SQL> grant create any directory to xdb;
Grant succeeded.
SQL> conn xdb/xdb
Connected.
SQL> create directory XMLDIR as 'C:"oracle"XMLDB';
Directory created.
創建存儲過程,從XML文件中讀取數據存儲到XML表中
create or replace function getClobDocument(
filename in varchar2,
charset in varchar2 default NULL)
return CLOB deterministic
is
file bfile := bfilename(‘XMLDIR’,filename);
charContent CLOB := ' ';
targetFile bfile;
lang_ctx number := DBMS_LOB.default_lang_ctx;
charset_id number := 0;
src_offset number := 1 ;
dst_offset number := 1 ;
warning number;
begin
if charset is not null then
charset_id := NLS_CHARSET_ID(charset);
end if;
targetFile := file;
DBMS_LOB.fileopen(targetFile, DBMS_LOB.file_readonly);
DBMS_LOB.LOADCLOBFROMFILE(charContent, targetFile,
DBMS_LOB.getLength(targetFile), src_offset, dst_offset,
charset_id, lang_ctx,warning);
DBMS_LOB.fileclose(targetFile);
return charContent;
end;
/
-- you can use getCLOBDocument() to generate a CLOB from a file containin
-- an XML document. For example, the following statement inserts a row into the
-- XMLType table Example2 created earlier:
向表中插入數據:
SQL> INSERT INTO XMLTABLE
2 VALUES(XMLTYPE(getCLOBDocument('init.xml')));
1 row created.
SQL> INSERT INTO XMLContent
2 VALUES(1, XMLTYPE(getCLOBDocument('init.xml', 'UTF8')));
1 row created.
SQL> commit;
Commit complete.
2.2 更新XML表數據
2.2.1普通Update方式
SQL> UPDATE XMLTABLE X SET VALUE(X)=XMLTYPE(getCLOBDocument('init.xml'));
1 row updated.
SQL> UPDATE XMLContent SET xmlvalue=XMLTYPE(getCLOBDocument('init.xml'))
2 WHERE keyvalue='1';
1 row updated.
SQL> commit;
Commit complete.
2.2.2使用updatexml()更新節點值
SQL> UPDATE xmlcontent
2 SET xmlvalue = updateXML(xmlvalue,
3 '/sqlstress/config/userName/text()',
4 'shanxi')
5 WHERE existsNode(xmlvalue,
6 '/sqlstress/config[userName="shanxi806"]') = 1;
1 row updated.
SQL> commit;
Commit complete.
SQL> select extractvalue(xmlvalue,'/sqlstress/config/userName')
2 from xmlcontent;
EXTRACTVALUE(XMLVALUE,'/SQLSTRESS/CONFIG/USERNAME')
---------------------------------------------------------------------
shanxi
2.2.3使用updatexml()更新一個節點樹
SQL> UPDATE xmlcontent
2 SET xmlvalue =
3 updateXML(xmlvalue,
4 '/sqlstress/functions/function[1]/parameters/prameter[2]/valuecope',
5 xmltype('<valueScope rangeType="RANGE" dataType="int">
6 <minValue>
7 13111111111
8 </minValue>
9 <maxValue>
10 13999999999
11 </maxValue>
12 </valueScope>'
13 )
14 )
15 WHERE existsNode(xmlvalue,
16 '/sqlstress/functions/function[1]/parameters/parameter[@pid=2]'
17 ) = 1;
1 row updated.
2.3 從XML表中讀取數據
主要利用extract(), extractValue(), and existsNode()等幾個函數。”Init.xml”的內容參見附錄。
2.3.1existsNode ()
EXISTSNODE函數檢查XML中的某一個節點是否存在。如果存在,返回1,否則返回0。
SQL> SELECT existsNode(value(X),'/sqlstress/config/connURL')
2 FROM XMLTABLE X;
EXISTSNODE(VALUE(X),'/SQLSTRESS/CONFIG/CONNURL')
------------------------------------------------
1
SQL> SELECT existsNode(value(X),'/sqlstress/config/connURLFalse')
2 FROM XMLTABLE X;
EXISTSNODE(VALUE(X),'/SQLSTRESS/CONFIG/CONNURLFALSE')
-----------------------------------------------------
0
SQL> SELECT existsNode(xmlvalue,'/sqlstress/config/connURL')
2 FROM XMLContent X
3 WHERE keyvalue = '1';
EXISTSNODE(XMLVALUE,'/SQLSTRESS/CONFIG/CONNURL')
------------------------------------------------
1
SQL> SELECT existsNode(value(X),
2 '/sqlstress/config[userPWD="'||chr(10)||' shanxi806'||chr(10)||' "'||']')
3 FROM XMLTABLE X;
EXISTSNODE(VALUE(X),'/SQLSTRESS/CONFIG[USERPWD="'||CHR(10)||'SHANXI806'||CHR(10)
--------------------------------------------------------------------------------
1
SQL> SELECT count(*)
2 FROM XMLContent x
3 WHERE existsNode(xmlvalue,'/sqlstress/config[userName="shanxi806"]') = 1;
COUNT(*)
----------
1
SQL> SELECT count(*)
2 FROM XMLContent x
3 WHERE existsNode(xmlvalue,'/sqlstress/functions/function[@id=1]') = 1;
COUNT(*)
----------
1
SQL> SELECT count(*)
2 FROM XMLContent x
3 WHERE existsNode(xmlvalue,'/sqlstress/functions/function/parameters/parameter[2][@pid=2]') = 1;
COUNT(*)
----------
1
2.3.2extractValue()
EXTRACTVALUE()是從某個節點中讀取值
SQL> select extractValue(xmlvalue, '/sqlstress/config/userPWD')
2 from xmlcontent
3 where keyvalue='1';
EXTRACTVALUE(XMLVALUE,'/SQLSTRESS/CONFIG/USERPWD')
----------------------------------------------------------------
shanxi806
SQL> SELECT extractvalue(xmlvalue, '/sqlstress/functions/function[1]/parameters/parameter[2]/@pid')
2 FROM xmlcontent
3 WHERE keyvalue = '1';
EXTRACTVALUE(XMLVALUE,'/SQLSTRESS/FUNCTIONS/FUNCTION[1]/PARAMETERS/PARAMETER[2]/
--------------------------------------------------------------------------------
2
ExtractValue只能返回一個確切的位置節點的值,如果存在多個相同節點,Oracle就會報錯:
SQL> SELECT extractvalue(xmlvalue, '/sqlstress/functions/function[1]/parameters/
parameter')
2 FROM xmlcontent
3 WHERE keyvalue = '1';
FROM xmlcontent
*
ERROR at line 2:
ORA-19025: EXTRACTVALUE returns value of only one node
SQL> SELECT extractvalue(xmlvalue, '/sqlstress/config')
2 FROM xmlcontent
3 WHERE keyvalue = '1';
FROM xmlcontent
*
ERROR at line 2:
ORA-19025: EXTRACTVALUE returns value of only one node
2.3.3Extract()
EXTRACT函數返回一個XML文檔的一個節點樹,或者某一節點下所有符合條件的節點。
返回一個節點樹:
SQL> set line 100
SQL> set lone 20000
SQL> SELECT extract(xmlvalue, '/sqlstress/config')
2 FROM xmlcontent
3 WHERE keyvalue = '1';
EXTRACT(XMLVALUE,'/SQLSTRESS/CONFIG')
-----------------------------------------------------
<config>
<connURL>
jdbc:oracle:thin:@10.71.111.231:1521:P51
</connURL>
<userName>shanxi806</userName>
<userPWD>
shanxi806
</userPWD>
<threadNum>
100
</threadNum>
<execNumPerThread>
1000
</execNumPerThread>
</config>
返回所有符合條件的節點:
SQL> SELECT extract(xmlvalue, '/sqlstress/functions/function[1]/parameters/parameter/paraType')
2 FROM xmlcontent
3 WHERE keyvalue = '1';
EXTRACT(XMLVALUE,'/SQLSTRESS/FUNCTIONS/FUNCTION[1]/PARAMETERS/PARAMETER/PARATYPE')
--------------------------------------------------------------------------------
<paraType>
String
</paraType>
<paraType>
String
</paraType>
<paraType>
int
</paraType>
<paraType>
String
</paraType>
<paraType>
String
</paraType>
<paraType>
float
</paraType>
<paraType>
int
</paraType>
2.3.4利用xmlsequence()和table()返回符合條件的節點的值:
SQL> SELECT extractValue(value(t),'/paraType')
2 FROM XMLContent,
3 TABLE( xmlsequence (
4 extract(xmlvalue,
5 '/sqlstress/functions/function[1]/parameters/parameter/paraType'))
6 ) t
7 WHERE keyvalue='1';
EXTRACTVALUE(VALUE(T),'/PARATYPE')
--------------------------------------------------------------------------------
String
String
int
String
String
float
int
2.4 XML的格式處理
2.4.1利用transform()函數將XSLT應用到XML上
SQL> update xmltable x set value(x)=XMLTYPE(getclobdocument('example.xml'));
1 row updated.
SQL> commit;
Commit complete.
SQL> SELECT value(t).transform(xmltype(getclobdocument('example.xsl')))
2 from XMLTABLE t
3 where existsNode(value(t),
4 '/PurchaseOrder[Reference="ADAMS-20011127121040988PST"]'
5 ) = 1;
2.4.2利用XMLTransform()函數進行格式處理
SQL> select xmltransform(value(t), xmltype(getclobdocument('example.xsl')))
2 from XMLTABLE t;
2.5 其他XMLType方法
CREATEXML () :一個用來創建XMLType實例的靜態方法。
ISFRAGMENT():如果XMLType包含一個文檔段則返回1。文檔段的意思就是一個沒有根節點的XML穩當。文檔段一般可以通過Extract()函數產生。
GETCLOBVAL():返回一個CLOB,它包含的內容是基于CMLType內容的XML文檔。
GETROOTELEMENT():返回XMLType中XML文檔的根元素的名稱。
GETNAMESPACE():返回XMLType中XML文檔的根元素的名稱。
3 XML存儲
3.1 結構化存儲還是非結構化存儲
關于結構化存儲和非結構化存儲的對比:
特性
|
非結構化XML存儲
|
結構化XML存儲
|
存儲技術
|
XMLType的字段和表的內容都是通過CLOB類型存儲
|
XMLType的字段和表的內容都是存為SQL對象的集合。默認情況下,基于schema的XMLType的字段和表的XML模型都是結構化的存儲方式
|
是否可以存儲非XML的基于schema的表
|
只有當XMLType的字段和表與XML schema無關時可以
|
只有當XMLType的字段和表是基于XML Schema時才可以。
|
性能:存儲和獲取速度
|
因為在存取操作時,不需要解析和重編譯,可以獲得很高的存取速度。
|
在存取時較慢。因為在存儲時需要將文檔切割,而在提取之前需要重新構造。
|
性能:操作速度
|
比結構化存儲方式更慢
|
較快
|
靈活性:是否能很容易被處理
|
具有較強的靈活性
|
與Oracle 9i的面向對象特性成反比
|
內存使用情況:XML文檔是否需要被解析
|
Oracle XML DB需要解析整個文檔到內存中
|
可以使用Oracle XML DB減少內存的使用,并通過以下方式優化對XMLType的字段和表基于DOM的操作:
Lazy Manifestation (LM)
Least Recently Used (LRU)
|
|
|
|
|
|
|
|