Oracle XML DB之浅入浅出

作者:fuyuncat

来源:WWW.HelloDBA.COM

备注:XML DBOracle 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.3XML文件中读取数据存储到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():返回XMLTypeXML文档的根元素的名称。

GETNAMESPACE():返回XMLTypeXML文档的根元素的名称。

3         XML存储

3.1    结构化存储还是非结构化存储

关于结构化存储和非结构化存储的对比:

特性

非结构化XML存储

结构化XML存储

存储技术

XMLType的字段和表的内容都是通过CLOB类型存储

XMLType的字段和表的内容都是存为SQL对象的集合。默认情况下,基于schemaXMLType的字段和表的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)

posted @ 2007-09-27 19:50  jimeper  阅读(3154)  评论(1编辑  收藏  举报