oracle XML DB的使用

来源:互联网 发布:软件研发部门职责 编辑:程序博客网 时间:2024/05/14 18:05

 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 deterministicis    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。

test XML文档,下面的语句都是基于此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>