`

oracle XML DB的使用

 
阅读更多

XML DB简介

Oracle XML DB 是一组专门为 XML 开发的内置高性能存储和检索技术,首次随 Oracle9i 数据库第 2 版推出。OracleXML DB 将 World Wide Web Consortium (W3C) XML 数据模型完全吸收到 Oracle9i 数据库中,并为导航和查询 XML 提供了新的标准访问方法。可以同时获得关系数据库技术和 XML 技术的所有优势。Oracle XML DB 可用于存储、查询、更新、转换或处理 XML,并使用 SQL 查询访问相同的XML 数据。

验证是否安装了 XML DB

运行SQL:select comp_name from dba_registry where comp_name like '%XML%';若返回的数据为:COMP_NAME/Oracle XML Database 则证明已经安装XML DB

接下来可以进行XMLDB的操作了

向XMLType或者XMLType column数据表中存放数据

当需要要向Oracle9i数据库中存储XML文档时,可以采取如下的这些方法,包括:

1.在Oracle9i数据库外部将XML文档进行解析,将分析所得到的结果以行的形式存入一个或者多个表中。在这种场景下,数据库不知道正在处理的是XML格式的内容。

2.将XML文档存储在Oracle9i数据库的CLOB或者VARCHAR2字段。这种场景下数据库仍然无法知道正在处理XML文档。但是用户可以使用XDK编写程序来执行XML操作。

3.把XML文档作为XMLType数据类型存储在Oracle9i数据库中。

使用以下两种方式都是有效的:

将XML文档存储在XMLType数据列中。

将XML文档存储在XMLType数据表中。

采用以上两种方式存储就意味着数据库能够知道正在处理的数据是XML文档,使用这种方法来存放XML文档将给我们带来很大的方便,因为Oracle9i数据库中提供了一系列的新特性,这使得对XML数据进行高效的处理变成了可能。

创建一个带 XMLType 数据列的表

CREATE TABLE XMLCONTENT(    
           KEYVALUE  varchar2(10)  primary key,    
           XMLCOLUMN SYS.xmltype
);   


创建一个XMLType表

CREATE TABLE XMLTABLE OF XMLType;


将XML文档转化XMLType实例,然后存储到XMLType表或者带XMLType数据列的表中

grant create any directory to xdb;
conn xdb/xdb
create directory XMLDIR as 'C:"oracle"XMLDB';
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;
/
-- create XMLDIR directory-- connect system/manager-- create directory XMLDIR as '<location_of_xmlfiles_on_server>';
-- grant read on directory xmldir to public with grant option; 
-- you can use getCLOBDocument() to generate a CLOB from a file containing
-- an XML document. For example, the following statement inserts a row into the 
-- XMLType table Example2 created earlier:

创建函数后即可使用此函数进行数据导入,可以看出我们把路径设置在C盘,此时只需将需导入的文件放在C盘即可,然后运行以下方法即可

INSERT INTO XMLTABLE VALUES(XMLTYPE(getCLOBDocument('test.xml')));

注意Charset参数的使用,它用来确定指定文件的字符集,如果该参数被忽略,将默认采用当前数据库所采用的字符集,例如在文档test.xml中使用的UTF-8,它可以被装载到XMLType数据表XMLTABLE数据表中:

insert into xmltable  values(xmltype(getClobDocument('test.xml','UTF-8')));

如果不使用Charset参数将默认使用ZHS16GBK.

insert into xmldoc values(xmltype(getClobDocument('test.xml')));


获取XMLType表或者带有XMLType数据列的表中的数据

一旦一组XML文档存储为许多XMLType表或者许多XMLType数据列之后,下一步要做的就是对存储的数据进行恢复操作。当需要对一组XML文档进行操作时,通常需两个基本工作要做:

决定怎样从一组XML文档中找到需要的子集。

决定怎样更优地从一组XML文档所包含的节点集(nodes)中找到需要的子集。

由于在Oracle9i数据库和XMLType数据类型提供了许多相关的函数使得上述的这些操作变得非常简单。这些函数使用W3C的XPath推荐标准来对一组XML文档中的数据进行导航。

在Oracle XML DB中使用Xpath

XML DB中提供的许多函数都是基于W3C Xpath推荐标准的。Xpath规范规定通过使用“/”符号来访问XML文档中的的元素和属性,例如/A/B,/A@name(name表示属性名)。在XML DB中使用XPath表达式和我们比较熟悉的SQl语句能很好地完成对XML文档的相关操作。

Xpath在Oracle XML DB中的主要作用是结合extract(),extractValue(),和existsNode()等函数来完成一些数据操作。

函数existsNode()的作用是判断在给定的XML文档中是否存在一个与Xpath表达式吻合的节点。如果文档中存在这么一个节点,函数将返回值1。

testXML文档,下面的语句都是基于此XML进行的

<PurchaseOrder >  
    <Reference>ADAMS-20011127121040988PST</Reference>  
        <Actions>    
           <Action>      
               <User>SCOTT</User>      
               <Date>2002-03-31</Date>    
           </Action>  
        </Actions>  
     <Reject/>  
     <Requestor>Julie P. Adams</Requestor>  
     <User>ADAMS</User>  
     <CostCenter>R20</CostCenter>  
     <ShippingInstructions>    
         <name>Julie P. Adams</name>    
         <address>Redwood Shores, CA 94065</address>    
         <telephone>650 506 7300</telephone>  
     </ShippingInstructions>  
     <SpecialInstructions>Ground</SpecialInstructions>  
     <LineItems>    
         <LineItem ItemNumber="1">      
              <Description>The Ruling Class</Description>      
              <Part Id="715515012423" UnitPrice="39.95" Quantity="2"/>    
         </LineItem>    
         <LineItem ItemNumber="2">      
              <Description>Diabolique</Description>      
              <Part Id="037429135020" UnitPrice="29.95" Quantity="3"/>    
         </LineItem>    
         <LineItem ItemNumber="3">      
               <Description>8 1/2</Description> <Part Id="037429135020" UnitPrice="29.95" Quantity="3"/>    
         </LineItem>  
      </LineItems>
</PurchaseOrder>

使用existNode()函数

exitstNode()语法示意图:

寻找一个与XPath表达式匹配的节点

在下面的程序中使用existsNode将返回值“1”:

SELECT existsNode(value(X),'/PurchaseOrder/Reference')   FROM XMLTABLE X; 
SELECT existsNode(value(X),'/PurchaseOrder[Reference="ADAMS-20011127121040988PST"]')   FROM XMLTABLE X;
SELECT existsNode(value(X),'/PurchaseOrder/LineItems/LineItem[2]/Part[@Id="037429135020"]')   FROM XMLTABLE X; 
SELECT existsNode(value(X),'/PurchaseOrder/LineItems/LineItem[Description="8 1/2"]')   FROM XMLTABLE X;   
SELECT existsNode(X.XMLVALUE, '/PurchaseOrder/LineItems/LineItem[Description="8 1/2"]')   FROM XMLCONTENT X;  

不存在与Xpath表达式匹配的节点

由于不存在与Xpath表达式相匹配的节点,existsNode将返回值0:

SELECT existsNode(value(X),'/PurchaseOrder/UserName')   FROM XMLTABLE X; 
SELECT existsNode(value(X),'/PurchaseOrder[Reference="ADAMS-XXXXXXXXXXXXXXXXXXXX"]')   FROM XMLTABLE X; 
SELECT existsNode(value(X),'/PurchaseOrder/LineItems/LineItem[3]/Part[@Id="037429135020"]')   FROM XMLTABLE X; 
SELECT existsNode(value(X),'/PurchaseOrder/LineItems/LineItem[Description="Snow White"]')   FROM XMLTABLE X;
SELECT existsNode(X.XMLVALUE,'/PurchaseOrder/LineItems/LineItem[Description="Snow White"]')   FROM XMLCONTENT X;

existsNode()

函数的最普遍的用法是将其放在SELECT,UPDATE,DELETE等SQL语句的where子句中。这种情况下,Xpath

表达式被传递给existsNode() 函数,where语句通过existsNode()函数的返回值来决定数据表中的哪一个XML文档将被SQl语句处理.

在where子句中使用existsNode()函数。

SELECT count(*)   FROM XMLTABLE x   WHERE existsNode(value(x),'/PurchaseOrder[User="ADAMS"]') = 1;  
DELETE FROM XMLTABLE x   WHERE existsNode(value(x),'/PurchaseOrder[User="ADAMS"]') = 1;  commit;

extractValue()函数也是以Xpath表达式为参数,将返回以XMLtype数据类型存放在数据库中的XML文档中的text节点或者节点属性值。这个返回值将以一般对象数据类型的形式返回。

该函数的语法示意图:

extractValue()函数的使用示例:extractValue()的有效使用示例

SELECT extractValue(value(x),'/PurchaseOrder/Reference')  FROM XMLTABLE X;

返回:
EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/REFERENCE')
------------------------------------------------------------------------
ADAMS-20011127121040988PST

SELECT extractValue(value(x),'/PurchaseOrder/LineItems/LineItem[2]/Part/@Id')  FROM XMLTABLE X;

返回:
EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM[2]/PART/@ID')
-----------------------------------------------------------------------
037429135020

extractValue()函数只能返回某一个text节点的的值或者某一个节点的属性值.以下是两个extractValue()函数的无效使用示例。在第一个示例中Xpath表达式可以匹配三个XML文档中的节点,在第二个例子中Xpath表达式指向的是一个树形节点而非某个text节点的值或者某一个节点的属性值。应此可以看到,这两种用法都是无效的使用方法。

extractValue()无效使用示例

SELECT extractValue(value(X),'/PurchaseOrder/LineItems/LineItem/Description')   FROM XMLTABLE X;

将extractValue() 使用在where子句中

extractValue() 也可以被放置在 SELECT,UPDATE, 或者DELETE 等SQL语句的where子句中. 这使得我们可以实现XMLType表之间的联接、带有XMLType数据列的表之间的联接、和其他的关系型数据表与XMLType之间的联接。以下的查询展示了怎样在SELECT清单中和where子句中使用extractValue()方法。

SELECT extractValue(value(x),'/PurchaseOrder/Reference')    FROM XMLTABLE X, SCOTT.EMP    WHERE extractValue(value(x),'/PurchaseOrder/User') = EMP.ENAME    AND EMP.EMPNO = 7876;

--返回:
-- EXTRACTVALUE(VALUE(X),'/PURCHASEORDER/REFERENCE')
-- --------------------------------------------------
-- ADAMS-20011127121040988PST

使用extract()函数

语法示意图3-3:

extract()函数用来获取Xpath指向的一组节点。这些节点将以XMLType实例的形式返回。extract() 函数的返回值既可以是一个XML文档也可以是XML文档片断。

使用 extract() 返回XML文档片断

下面的程序使用extract()函数返回XMLType实例。 该实例是一个包含了Xpath所指向的一组Description节点.

SELECT extract(value(X), '/PurchaseOrder/LineItems/LineItem/Description')  FROM XMLTABLE X;

-- 返回:
-- EXTRACT(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM/DESCRIPTION')
-- ------------------------------------------------------------------
-- <Description>The Ruling Class</Description>
-- <Description>Diabolique</Description>
-- <Description>8 1/2</Description>

用 extract() 函数返回 一棵 XPath 表达式指向的节点树

SELECT extract(value(X),'/PurchaseOrder/LineItems/LineItem[1]')  FROM XMLTABLE X;

返回:
EXTRACT(VALUE(X),'/PURCHASEORDER/LINEITEMS/LINEITEM[1]')
-------------------------------------------------------------------------

<LineItem ItemNumber="1"> <Description>The Ruling Class</Description> <Part Id="715515012423" UnitPrice="39.95" Quantity="2"/></LineItem>

使用XMLSequence()函数

XMLSequence语法示意图:

XMLSequence()函数可以将XML文档片断转化为一系列的XMLType实例。XMLSequence()函数可以通过获取一个包含XML文档片段的XMLType实例来返回

XMLType对象。 这一组对象的中的每一个对象对应一个XML文档片断中的一个根级的节点。 最后,使用SQL TABLE()函数就可以将这一组对象转化为数据

行集合。

使用XMLSequence() 和 TABLE()函数从XML文档中提取Description 的节点值

set long 10000 
set feedback onSELECT extractValue(value(t),'/Description')  FROM XMLTABLE X,TABLE ( xmlsequence ( extract(value(X), '/PurchaseOrder/LineItems/LineItem/Description') )  ) t;

返回:
EXTRACTVALUE(VALUE(T),'/DESCRIPTION')
-------------------------------------------------------------------------
The Ruling Class
Diabolique
8 1/2

使用updateXML()方法来更新XML文档

语法示意图:

updateXML() 函数可以用来对XML文档中的节点的属性值,节点,text节点值,树形节点进行更新。更新的对象的位置由Xpath表达式来指定。

以下的程序展示了如何对以XMLType形式存放在数据表中的XML文档进行更新操作。

使用 updateXML()方法来对XPath表达式所指定的Text节点的值进行更新

XPath表达式为`/PurchaseOrder/Reference':

UPDATE XMLTABLE t SET value(t) = updateXML(value(t), '/PurchaseOrder/Reference/text()','MILLER-200203311200000000PST') WHERE existsNode(value(t),'/PurchaseOrder[Reference="ADAMS-20011127121040988PST"]') = 1;

返回:

1 row updated.

SELECT value(t) FROM XMLTABLE t;

This returns:

VALUE(T)

-------------------------------------------------------------------------

<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.oracle.com/xdb/po.xsd">
<Reference>MILLER-200203311200000000PST</Reference>
</PurchaseOrder>

使用 updateXML() 函数来替代Xath表达式所指定的树形节点

XPath 表达式: `/PurchaseOrders/LineItems/LineItem[2]'.

UPDATE XMLTABLE t
  SET value(t) = 
  updateXML(value(t),
            '/PurchaseOrder/LineItems/LineItem[2]',
            xmltype('<LineItem ItemNumber="4">
                       <Description>Andrei Rublev</Description>
                       <Part Id="715515009928" UnitPrice="39.95"
                             Quantity="2"/>
                     </LineItem>'
           )
)
  WHERE existsNode(value(t),
        '/PurchaseOrder[Reference="MILLER-200203311200000000PST"]'
  ) = 1;

返回:

1 row updated.

SELECT value(t) FROM XMLTABLE t;

返回:

VALUE(T)

------------------------------------------------------------------------

<PurchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.oracle.com/xdb/po.xsd">
<Reference>MILLER-200203311200000000PST</Reference>
<LineItems>
<LineItem ItemNumber="1">
<Description>The Ruling Class</Description>
<Part Id="715515012423" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="4">
<Description>Andrei Rublev</Description>
<Part Id="715515009928" UnitPrice="39.95" Quantity="2"/>
</LineItem>
<LineItem ItemNumber="3">
<Description>8 1/2</Description>
<Part Id="037429135624" UnitPrice="39.95" Quantity="4"/>
</LineItem>
</LineItems>
</PurchaseOrder>







分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics