Oracle编程入门经典 第4回 新9i示例模式。Oracle XQuery查询、构建和转换XML

Oracle 9i产品帮助文档:

在 Oracle 数据库 10g 第 2 版中,Oracle
引入了一个跟该数据库集成的通通效于带 XQuery
引擎,该引擎可用于完成与开支支持 XML 的应用程序相关的各种任务。XQuery
是平种用于拍卖 XML 数据模型的询问语言,它事实上可操作任何类型的可用 XML
表达的数码。尽管 Oracle XQuery
实施而你可以使数据库数据与外部数据源,但当处理数据库中蕴藏的结构化数据方面,Oracle
XML DB 通常可以显著加强性能。

http://docs.oracle.com/cd/B10501_01/index.htm

本文提供的以身作则不仅示范了当什么场合下与哪些利用 XQuery 查询、构建和更换
XML,而且还以身作则了如何监督及剖析 XQuery
表达式的性执行,从而找到更高效之方来拍卖同工作负荷。

只是依据自己索要开展询问,包含了成千上万的文档。

根据关系数据构建 XML

 

每当急需之情状下(例如,向 Web 服务发送结果),您可能只要因关系数据构建
XML。要在 Oracle 数据库 10g 第 2
版之前的版中就这个任务,通常需用 SQL/XML 生成函数,如
XMLElement、XMLForest 和 XMLAgg()。在 Oracle 数据库 10 g 第 2
版中,XQuery 将于这些函数更为迅速。具体而言,在 XQuery 表达式内部用
ora:view XQuery 函数,您可查询现有的涉表或视图以及马上构建
XML,从而无需经过关系数据显式创建 XML 视图。列表 1 中之 PL/SQL
代码演示了哪些运用 ora:view 基于示例数据库模式 HR
的默认员工干表中蕴藏的数量构建 XML 文档。

Sample Schemas的目录:

列表 1:使用 ora:view 基于关系数据创建 XML

http://docs.oracle.com/cd/B10501_01/server.920/a96539/toc.htm

BEGIN
IF(DBMS_XDB.CREATEFOLDER('/public/employees')) THEN
DBMS_OUTPUT.PUT_LINE('Folder is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create folder');
END IF;
COMMIT;
END;
/
DECLARE
XMLdoc XMLType;
BEGIN
SELECT XMLQuery(
'for $j in 1
return (
{
for $i in ora:view("HR", "employees")/ROW
where $i/EMPLOYEE_ID <= 102
return (
{xs:string($i/EMPLOYEE_ID)}
{xs:string($i/LAST_NAME)}
{xs:integer($i/SALARY)}
)} )'
RETURNING CONTENT) INTO XMLdoc FROM DUAL;
IF(DBMS_XDB.CREATERESOURCE('/public/employees/employees.xml', XMLdoc)) THEN
DBMS_OUTPUT.PUT_LINE('Resource is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/

 

当列表 1 中之首先单 PL/SQL 过程被,您才是于 XML
信息库中开创了一个初文件夹。在该信息库文件夹着,您就以积存此处显示的老二个
PL/SQL 过程遭到开创的 XML 文档。第二只 PL/SQL 过程首先有 SELECT
语词,该语句以 XMLQuery SQL 函数基于关系数据构建 XML。对于 XQuery
表达式(XMLQuery 于这边将那作参数)而言,请留心嵌套的 FLWOR
表达式中使用的 ora:view XQuery 函数。在该示例中,ora:view
获取两独输入参数,即“HR”和“employees”,它们指示该函数查询属于 HR
数据库模式之员工表。因此,ora:view 将回来一个象征 HR.employees
表行的员工 XML
文档序列。但为节约结果文档中之空中,只将眼前三个员工记录传递让结果序列。这是透过以
FLWOR 表达式的 where 子句被指定 $i/EMPLOYEE_ID <= 102
而实现的。请留意 FLWOR 表达式的 return 子句被采取的 xs:string()
xs:integer() XQuery 类型表达式。实际上,此处使用的立即点儿单 XQuery
表达式不仅用 XML
节点值转换为相应的种,而且还以取这些节点值。随后,生成的职工 XML
文档作为 employees.xml 保存及之前以列表 1 中其他一个 PL/SQL 过程中创造的
/public/employees XML 信息库文件夹。要保这操作都形成,可实施以下查询:

Sample Schemas的文档(示例模式的表及介绍):

SELECT XMLQuery('for $i in fn:doc("/public/employees/employees.xml")
return;
$i'
RETURNING CONTENT) AS RESULT FROM DUAL;

http://docs.oracle.com/cd/B10501_01/server.920/a96539.pdf

拖欠查询应生成以下输出:

 


100
King
24000


101
Kochhar
17000


102
De Haan
17000

众年来,Oracle教师、管理员、程序员、以及用户为学习、测试或调整他们之数据库,都一直于动用此值得依靠之SCOTT模式开展着简单地查询、更新、以及去除操作。这些模式就是是咱所说之演示模式。示例模式是发明、视图、索引这样的数据库对象的聚合,并且随着预先供了象征有点框框还是中等规模企业之数。

于以上 XQuery 中,fn:doc XQuery 函数用于访问 Oracle XML DB
信息库中储存的单个 XML 文档。但如若如拍卖部分备相同或相似结构的 XML
文档(存储在同一 XML
信息库文件夹中),应该怎么开?这种气象下,另一个用来拍卖 XML
信息库资源的 XQuery 函数(即
fn:collection)可能会见派上用场。本文稍后将介绍几个关于如何使
fn:collection XQuery 函数的以身作则。

趁最新版本的Oracle数据库Oracle
9i的产出,又引进了崭新的相同组示例模式,它们的对象是扩大SCOTT模式为用户提供的效应。所有这些模式并形成了同之虚拟号的一致有的,它们各自都生和好的作业中心。例如,人力资源部、订单输入部门及发货部门还来分别之模式。

查询 XMLType 数据

注意:

XQuery 使您得操作基于 XML
模式及非基于模式之数码。以下示例演示了如何用 XMLTable 函数从 OE
演示数据库模式遭遇查询基于 PurchaseOrder XML 模式之 XMLType 表。

当下hr已经锁定了(即lock)。需要实行以下脚本:

SELECT ttab.COLUMN_VALUE AS OrderTotal FROM purchaseorder,
XMLTable(
'for $i in /PurchaseOrder
where $i/User = "EABEL"
return;

{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
) ttab;
SQL> connect system/zyf;

已连接。

SQL> alter user hr account unlock;

用户已更改。

SQL> alter user hr identified by hr;

用户已更改。

SQL> connect hr/hr;

已连接。

SQL> select table_name from user_tables;

TABLE_NAME

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

COUNTRIES

DEPARTMENTS

EMPLOYEES

JOBS

JOB_HISTORY

LOCATIONS

REGIONS

已选择7行。

于上述示例中,您当 XMLTable 函数的 PASSING 子句被采用 OBJECT_VALUE
虚拟列将 purchaseorder 表作为左右文项传递给此使用的 XQuery
表达式。XQuery 表达式计算用户 EABEL
请求的每个市订单的共计,并也拍卖的每个订单生成一个 OrderTotal XML
元素。要顾生成的 XML,请用 SELECT 列表中的 COLUMN_VALUE
虚拟列。最终之出口应如下所示:

4.1 SCOTT模式

所提供的SCOTT模式可供有示例表以及数额,来展示数据库的一对特征。它是一个一定简单的模式,如图4-1数据结构图所示(通过PowerDesign逆向工程转换为数据库模型)。

图4-1 SCOTT模式数据结构图

 大红鹰葡京会娱乐 1

为何要拿此模式命名吧SCOTT呢?SCOTT/TIGER是Oracle版本1、2和3时代底Oracle数据库的前期用户名/密码组合。SCOTT是因Oracle公司之泰山北斗程序员Bruce
Scott。当然,TIGER是Bruce养的猫的名字。

SCOTT模式遭遇所显示的数据库特性通常为看是大多数关系数据库产品遭的根本特征。如果想如果忠实地显示Oracle数据库的效果,就要强化这些示例!

ORDERTOTAL
-------------------------------------------------------------

EABEL-20021009123338324PDT
1328.05


EABEL-20021009123335791PDT
2067.15


EABEL-20021009123336251PDT
289.6


EABEL-20021009123336382PDT
928.92

4.2 Oracle 9i示例模式

Oracle技术好应用叫各种不同的条件中。技术解决方案的有限单下最气象是,高速在线事务处理和数据库仓库。尽管用户可用一个模式,展示什么在相同之表中完成在线事务处理和数据仓库。但是用户不用容许利用这种方法贯彻实用的解决方案。我们于今天之业界面临常可以发现,为了解决实际世界中的两样计算需求,通常以独立的数据库实例中见面是不同之模式,或者以网达到会见起大气分布式数据库。新的Oracle
9i示例模式模型极好地指向斯现象建模。

Oracle
9i示例模式试图模型化一个有血有肉世界面临持有同等系列典型工作单位的行销团队。这些不同的机关有着不同之信息技术需要,每一个示范模式都采取了不同的Oracle技术来解决它们各自的问题。另外,每个模式设计方案都指向一定的艺用户。这些模式如下:

  • HR——人力资源。
  • OE——订单输入。
  • PM——产品媒体。产品媒体当数据库中蕴藏了商家系列产品的相关多媒体内容,可以用来在Web上发表暨打印。PM利用了Oracle
    Intermedia,它特别规划用来拍卖发布音频、视频与可视数据的多媒体领域。另外,PM也屡地动用了LOB列类型。
  • QS——队列运送。运送部门各负其责记录企业向客户开展的产品运载情况,并且以6个模式来就这项工作。QS、QS_ES、QS_WS、QS_OS、QS_CB和QS_CS构成了排运送模式的汇聚。
  • SH——销售历史。

假定收获同样的终极结果,可以改用 XMLQuery 函数。但只要以达成一个示范中以的
XQuery 表达式参数传递给 XMLQuery(如下所示):

4.2.1 深入座谈各个模式

SELECT XMLQuery('for $i in /PurchaseOrder
where $i/User eq "EABEL"
return 
{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
RETURNING CONTENT)
FROM purchaseorder;

1. 人力资源

人力资源模式,或者HR模式,负责管理部门、雇员、工作同薪金信息。图4-2示了HR模式之详尽数据结构图示。

大红鹰葡京会娱乐 2

则 XQuery 表达式返回的空序列将和 purchaseorder
表联接,从而包含在询问总结果集中。实际上,这意味输出将不仅带有为用户
EABEL 请求的订单生成的 OrderTotal 元素,而且还蕴藏为 purchaseorder
表中蕴藏的具有其他订单生成的空行(默认情况下,purchaseorder 表包含 132
行)。从结果集中拔除空行的主意有是于 SELECT 语句子之 WHERE 子句被动用
existsNode SQL 函数,而无是以 XQuery 表达式中使 WHERE 子句,如下所示:

2. 订单输入

订单输入(Order
Entry)模式,或者OE模式,可以据此来治本公司从事商务活动的逐条渠道中之客户、销售订单和活库存。

图4-3详实写了OE模式的数据结构。就如我辈以前了解的,与人力资源模式相比,订单输入模式更加复杂。

大红鹰葡京会娱乐 3

希冀4-3 OE模式数据结构

OE模式会记录产品库存。我们拿会储存任意指定仓库中指定产品的数量。在小卖部受会生出多独仓库,所以只要采取地点标识符指出那个地理区域。在WAREHOUSES表中还有一个Oracle
Spatial列,它为我们提供了采用Oracle Spatial空间技术的钥匙。

Oracle Spatial是于数据库被支持位置数据以及地理数据的艺。

在OE模式受到,需要顺便提供提及两个数据库对象模型:

  • CUST_ADDRESS_TYP。这是一个每当CUSTOMERS表中使用的对象类型。它蕴含了过多和客户地址有关的性。

SQL> desc cust_address_typ;

名称 是否为空? 类型

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

STREET_ADDRESS VARCHAR2(40)

POSTAL_CODE VARCHAR2(10)

CITY VARCHAR2(30)

STATE_PROVINCE VARCHAR2(10)

COUNTRY_ID CHAR(2)
  • PHONE_LIST_TYP。这是一个VARCHAR2(25)的VARRAY。这个VARRAY在CUSTOMERS表中作为独立的排列存储,可以用来存储最多5单电话号码。

SQL> desc phone_list_typ;

phone_list_typ VARRAY(5) OF VARCHAR2(25)

OE模式是一个可怜好之言传身教,它显示了正式的供组织或电脑零售商店可以使啊法去管理它们完整订单处理过程。通过动订单输入表中的数量,销售团队便好望地下的客户提供标准的产品信息,接受销售订单,量化订单收入,存储客户信息,为不同地理位置订购产品之客户提供标准的库存信息,以及其它服务。

SELECT XMLQuery('for $i in /PurchaseOrder
return 
{$i/Reference}

{fn:sum(for $j in $i/LineItems/LineItem/Part
return ($j/@Quantity*$j/@UnitPrice))}

'
PASSING OBJECT_VALUE
RETURNING CONTENT) AS ordertotal
FROM purchaseorder
WHERE existsNode(OBJECT_VALUE, '/PurchaseOrder[User = "EABEL"]') = 1;

3. 成品媒体

出品媒体(Product
Media)模式,或者PM模式,用于管理描述公司产品的多媒体数据。视频、音频和图像这样的在线媒体还得以按照输出的传媒数据类型存储在数据库被。这是我们设特别研究的模式之一,它至关重要于多媒体内容,以及Oracle
Intermedia所提供的功效。

注意:

Oracle Intermedia是Oracle数据库支持多媒体内容类型的机件。

除此之外Intermedia数据存储以外,PM模式还专门依赖LOB列类型的使来储存数据。

活媒体模式是Oracle 9i使用名也Oracle
Intermedia的Oracle技术解决具体世界商务需求的良示例。例如,我们虚构的店铺便好储存多媒体数据或者输出多媒体数据。因此,产品媒体模式受到的示范可以成功如下工作:

  • 为Oracle中采取Web发布之始末存储缩略图和完全尺寸的图像。
  • 当Oracle中存储音频剪辑。
  • 以Oracle中储存视频剪辑。
  • 本着图像类型进行拍卖,以便转换成为与Web兼容的图像类型

运Oracle
Intermedia,一些曾经非常麻烦实现之任务便变得相对简单。图4-4代表也活媒体模式,以及它们对订单输入表PRODUCT_INFORMATION的引用。

大红鹰葡京会娱乐 4

祈求4-4 PM模式数据结构

PRINT_MEDIA表拥有一个对象类型(ADHEADER_TYP),以及在表的逐一记录受储存的对象嵌套表(TEXTDOC_TAB)。

ORDSYS.ORD__排都是一个Intermedia对象类型。这些Intermedia对象类型不仅可以储存图像、音频、视频这样的二进制数据;还好储存各种与多媒体类型有关的第一数据。

SQL> desc ordsys.ordimage;

上述查询和本有的开始的 XMLTable 示例生成相同的输出。

4. 序列运送

俺们的杜撰号想只要运用信息网,以方便在线客户拓展自助订货。当客户初始化订货的时刻,系统便得树立订单,向客户提供账单,并且要保证好依据客户的位置,通过当的所在发送订货。

QS_CS模式来一个号称吧ORDER_STATUS_TABLE的发明,可以储存订单状态。这是以整队列运送模式安装过程遭到绝无仅有建立表(除了通过高档队列API建立之班表外)。我们不见面显示同申有关的数据结构图,而是使讨论吗队列运送模式所建立的行列系统遭到之音流程。

图4-5所示流程图示中好见见,为了供一个清晰、直观的订购——发货——结算循环,要在机关期间怎么传递信息。

大红鹰葡京会娱乐 5

贪图4-5 为队列运送(QS)模式在列系统遭到树立之音流程

全体还设起图示顶部的订单输入开始。Oracle
Input(订单输入)过程所特别成的订单会放入New Order
Queue(新订单队列)中。这个行列要Oracle
Entry应用处理,然后会用订单放到Booked Orders
Queue(登记订单队列)中。再用Booked Orders
Queue中的订单发于适中的运中心(East(东部)、West(西部)或者Overseas(海外)),以及客户服务机关。

于这儿,运送中心便见面收取要水到渠成的订单,并且向客户发送订货,而且客户服务机构吧会见发现及订单的状态。在适用的运输中心,Shipping
Center(运送中心)应用即会见负担发送订货,或者以预订调整回订单状态。一旦取得了出品,就会发送退回吗订单状态的产品,并且用订单放到shipped
orders(已运订单)队列中。

当订单发送后,就会见经shipped orders
gueue通知客户服务与客户结算部门,并且向客户发送账单。经过结算的订单会放在Billed
Orders(已结算订单)队列中,它见面打招呼客户服务机关,然后就是可成功订单处理过程。

询问 Oracle XML DB 信息库中的 XML 数据

5. 售货历史

而今商务环境遭到之信用社曾经发现,除非人们能以同样栽出含义并且就算经常的方,根据信生成精确的裁定报告,否则世界上的享有销售信息还是毫无价值的。决策支持(decision
support)就是用来叙述在进展决策的经过遭到信息技术运用的术语。

销售历史模式是一个风数据仓库的言传身教。表会按照星型模式(star
schema)设计进行组织,在这种办法下,会时有发生一个坏之SALES表位于中心,SALES表的之外还会产生一部分微之查询表,或者维数(dimension)表。SALES表通常会生恢宏底数量(所有的销售实时),而维数表相对于SALES表来讲会相当小。

图4-6之数据结构图显示了销售历史模式:

大红鹰葡京会娱乐 6

贪图4-6 销售历史模式数据结构

为访 Oracle XML DB 信息库中蕴藏的 XML 数据,Oracle XQuery 引入了
fn:doc 和 fn:collection XQuery 函数。使用 fn:doc,您可查询 XML
信息库中蕴藏的么 XML 文档,而 fn:collection
使您可以拜同信息库文件夹着蕴藏的基本上单 XML 文档。

4.2.2 渐进上道

按照不同之受众组织模式的方式可鼓励新的Oracle用户通过结构化的法子上技能。例如,初家可以从人力资源开始。这可叫他深谙关系概念、查询数据、数据库操作语言、数据库定义语言、以及有别基本概念。

当新Oracle用户熟悉了人力资源模式下,可以连续分析订单输入模式。在斯新模式面临,他将会见逢对象类型、XML支持、Oracle
Spatial、以及其它组成部分较高档的数据库特性。

连通下去,用户可分析任何模式所提供的特定领域。多媒体专家可深入学产品媒体模式。设计发布-订阅型基于消息的体系的用户可窥见,队列运送模式在他们初步学习Oracle高级队列的时用会非常有帮带。数据仓库的热衷者最好去分析与了解销售历史模式。

凑巧而本文之前(参阅使用关系数据构建 XML部分)介绍的演示所示范,使用
fn:doc 非常简单直接。它赢得表示信息库文件资源 (URI) 的字符串并赶回该 URI
指向的文档。要询问 fn:collection XQuery
函数的企图,同一文件夹着至少该两独信息库文件。如果就运行了列表 1
中之代码,则早就创办了 /public/employees 信息库文件夹并以中存储了
employees.xml 文件。因此,您将需在该文件夹着至少还创一个 XML
文件,然后才会试用 fn:collection。列表 2 中的 PL/SQL 代码基于
SCOTT/TIGER 演示数据库模式的 dept 和 emp 表存储的关系数据构建
XML,然后用扭转的 XML 文档作为 acc_dept.xml 保存至 /public/employees
信息库文件夹。要运行列表 2 中之 PL/SQL 过程,请保管以 SCOTT/TIGER
的位置登录。

4.2.3 发现又多关于示例模式之始末

列表 2:基于关系数据构建 XML 并拿其保存至 XML 信息库

1. 数据库对象描述

当及时有的被,我们将会晤浏览数据库,找到属于示例模式下之靶子,然后利用SQL查询直接从数据库中拿走这些目标的定义。

注意:

以下试验部分所待的浑下面论都可于http://www.wrox.com/的本书可下载代码中收获。

考:获取数据库列表

将以下脚本保存至用户本地硬盘上称之为也dbls.sql的文本被(C:\oracle\ora92\bin,即sql*plus工作目录)

column object_name format a30

column tablespace_name format a30

column object_type format a12

column status format a1

break on object_type skip 1

select object_type,object_name,

decode(status,'INVALID','*','') status,

tablespace_name

from user_objects a,user_segments b

where a.object_name=b.segment_name(+)

and a.object_type=b.segment_type(+)

order by object_type,object_name

/

column status format a10

运作以下代码可取得数据库对象列表:

SQL> connect hr/hr;

已连接。

SQL> @dbls
DECLARE
XMLdoc XMLType;
BEGIN
SELECT XMLQuery(
'for $j in ora:view("SCOTT", "dept")/ROW
where $j/DEPTNO = 10
return ( 
{$j/DEPTNO,
$j/DNAME}
 {
for $i in ora:view("SCOTT", "emp")/ROW
where $i/DEPTNO = $j/DEPTNO
return (

{$i/EMPNO,
$i/ENAME,
$i/SAL}
)} 

)'
RETURNING CONTENT) INTO XMLdoc FROM DUAL;
IF(DBMS_XDB.CREATERESOURCE('/public/employees/acc_dept.xml', XMLdoc)) THEN
DBMS_OUTPUT.PUT_LINE('Resource is created');
ELSE
DBMS_OUTPUT.PUT_LINE('Cannot create resource');
END IF;
COMMIT;
END;
/

2. 起说模式

Oracle提供了同样栽可以让表的主人在数据库中存储表或者列的纯文本注释的法门。在示范模式安装期间,每个模式都有着一个剧本,可以啊它各自的表及排建立这些注释。这足以采取SQL命令CREATE
COMMENT实现。其中注释样本如下:

COMMENT ON TABLE jobs

IS ‘jobs table with job titles and salary ranges.Contains 19 rows.

References with employees and job_history table.’;

此刻,/public/employees
信息库文件夹应涵盖两个文本:acc_dept.xml(由列表 2 中之 PL/SQL
代码生成)和 employees.xml 文件(由列表 1 中之代码生成)。由于这些 XML
文档存储于平等信息库文件夹着,因此好采用 fn:collection 函数访问片单
XML 文档中储存的员工信息。然而,尽管这些 XML 文档均隐含员工 XML
元素(这些元素实际上有同等结构),但 XML 文档本身的组织迥然不同。在
employees.xml 中,文档根元素为 EMPLOYEES,而 acc_dept.xml 将 DEPARTMENT
用作根元素。要化解之题材,可以经过 XQuery 使用 XPath // 构造,从而导航及
XML 文档中之某节点,而无需指定该节点的宜路径。以下示例演示了争当
XQuery 表达式中以 XPath // 构造:

4.3 小结

文章根据自己清楚浓缩,仅供参考。

选择自:《Oracle编程入门经典》 清华大学出版社 http://www.tup.com.cn/

SELECT XMLQuery(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
order by $i/ENAME
return;
$i'
RETURNING CONTENT) FROM DUAL;

拖欠组织应生成以下输出:

102
De Haan
17000


7839
KING
5000


100
King
24000


101
Kochhar
17000

乃可看来,以上输出包含从 employees.xml 和 acc_dept.xml 中取得的职工
XML 元素,这些因素表示薪酬过或等于 5,000 美元之职工。

拿 XML 分解为关系数据

倘若应用程序处理关系数据而非 XML,而若得看的数额因 XML
格式存储,则用 XML
分解为关系数据可能会见大实惠。继续拓展上有之示范,您得行使 SQL
函数 XMLTable 将员工 XML 元素分解为虚拟表的单个列,如下所示:

SELECT emps.empno,emps.ename, emps.sal FROM 
XMLTable(
'for $i in fn:collection("/public/employees")//EMPLOYEE
where $i/SAL >= 5000
return;
$i'
COLUMNS empno NUMBER PATH '/EMPLOYEE/EMPNO',
ename VARCHAR2(30) PATH '/EMPLOYEE/ENAME',
sal NUMBER PATH '/EMPLOYEE/SAL') emps;

拖欠查询将转变以下输出:

EMPNO ENAME SAL
----- -------------- ----------
7839 KING 5000
100 King 24000
101 Kochhar 17000
102 De Haan 17000

询问表数据源

动用 XQuery,可以根据 XML 数据和可以用 XML 表示的非 XML 数据生成 XML
文档,无论其岗位怎么:无论是存储于数据库被、置于网站上、即时创建或者存储于文件系统中。但一旦顾,Oracle
XML DB 为对数据库被储存的数额开展的 XML
操作提供了很大的属性和可伸缩性。因此,如果你能完全控制所处理的数,则极端好拿它们移动至数据库中。

巧使您打前方的言传身教中询问及之,在 Oracle XQuery 实施被,doc 和 collection
XQuery 函数用于访问 Oracle XML DB 信息库中存储的 XML 文档。可以通过
XMLTable 和 XMLQuery SQL 函数中的 PASSING
子句动态绑定外部数据源。考虑以下示例。假设你的公司只要也那些从事为 XQ
项目之员工付出奖金。因此,财务部发布了 empsbonus.xml
文件,其中蕴含有资格取得奖金之员工列表以及该列表中输入的每个员工的奖金数目。empsbonus.xml
文件或者如下所示:

100
1200


101
1000

以实际上状况遇,以上之 XML
文件或者坐网站上(因此得以经互联网取)、以文件形式储存于该地文件系统中,或因为文件资源形式储存于
Oracle XML DB
信息库中。就本示例而言,该公文在网站及。为简单起见,可以在目(Web
服务器在里面存储可打 Web
看到底文档)中创造一个职工文件夹,然后以拖欠公文夹着插 empsbonus.xml
文件,以便可以经过以下 URL 访问 empsbonus.xml 文件:

http://localhost/employees/empsbonus.xml

连片下去,假要您需依据 empsbonus.xml
文档中存储的数目创建一个表。在拖欠表被,您或许不仅使含有列表中展示的奖金数量与每个员工的职工
ID,还要包含他/她底全名。因此,可以率先利用以下查询生成一个初的 XML
文档(假设你为 HR/HR 的位置连接):

SELECT XMLQuery(
'for $k in 1
return (
 {for $i in ora:view("employees")/ROW,
$j in $emps/EMPLOYEES/EMPLOYEE
where $i/EMPLOYEE_ID = $j/EMPNO
return (
{xs:string($i/EMPLOYEE_ID)}
{xs:string(fn:concat($i/FIRST_NAME, " ", $i/LAST_NAME))}
{xs:integer($j/BONUS)}
)} )'
PASSING xmlparse (document httpuritype
('http://localhost/employees/empsbonus.xml').getCLOB()) as "emps"
RETURNING CONTENT).getStringVal() as RESULT FROM DUAL;

以上查询是一个关于如何以 XQuery 基于 XML 及非 XML
数据(以不同的道于不同之数码源中检索)生成 XML
文档的以身作则。具体而言,使用 ora:view() 函数访问 HR 演示模式面临之默认
employees 关系表,并使用 PASSING 子句被的 httpuritype() 函数借助于
HTTP 访问 empsbonus.xml 文档。然后,在 FLWOR 表达式的 return
子句被构建新的 XML 文档。最后,将取以下 XML 文档:


100
Steven King
1200


101
Neena Kochhar
1000

缓解性能问题

正好而你于眼前的有的中了解及的,XQuery 是一样栽用于查询 Oracle 数据库存储的
XML 内容的快捷方法 – 无论你是拍卖地方存储的 XMLType
数据或者查询基于关系数据构建的 XML
视图。但因对数据以的储存类型的例外,XQuery
表达式的实施性可能截然不同不同。尤其是,Oracle XML DB 可以优化基于由
ora:view 函数创建的 SQL/XML 视图而构建的 XQuery 表达式。对于 XMLType
表或列着蕴藏的 XML 数据,只能针对采用结构化(对象-关系)存储技术存储的冲
XML 模式之 XMLType 数据开展 XQuery 优化。

所选取的蕴藏模型并非是影响 XQuery
表达式执行性的绝无仅有要素。在好几情况下,XQuery
表达式本身的布局也或导致性问题。要监控 XQuery
表达式的性能,可以打印并检查涉的 EXPLAIN PLAN。在 SQL*Plus
中,只需要安装 AUTOTRACE 系统变量,即可打印 SQL
优化程序下的施行路径。但若尽该操作,请保管创建 PLUSTRACE
角色,然后用其给连接到数据库所采取的用户。有关如何实行这个操作的音讯,请参见
Oracle 数据库 10g 第 2 版 (10.2) 文档中《SQL\Plus
用户指南和参照》一如既往题被的“调整
SQL\
Plus”一章节。以下示例演示了怎样通过检查 EXPLAIN PLAN
生成的推行计划来获得利益。假设你曾经用 PLUSTRACE 角色与默认用户 OE,以
OE/OE 的身份登录并运行以下查询:

SET AUTOTRACE ON EXPLAIN
SELECT count(*)
FROM oe.purchaseorder, XMLTable(
'for $i in /PurchaseOrder/User
where $i = "CJOHNSON"
return $i'
PASSING OBJECT_VALUE) ptab;

及时将转移以下输出:

COUNT(*)
----------
9
Execution Plan
---------------------------------------------
Plan hash value: 4046110317
--------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 226 | 29 (0) | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 226 | | |
| 2 | NESTED LOOPS | | 10782 | 2379K | 29 (0) | 00:00:01 |
|* 3 | TABLE ACCESS FULL | PURCHASEORDER | 1 | 226 | 5 (0) | 00:00:01 |
| 4 | COLLECTION ITERATOR P| XMLSEQUENCEFROMX| | | | |
Predicate Information (identified by operation id):
---------------------------------------------------
3 - filter(SYS_CHECKACL("ACLOID","OWNERID",xmltype('...

若或许针对啊上述查询生成的执行计划并无顺心。尤其是,所拍卖的行数可能坏大。由于
SQL
调整的机要对象是避看对结果莫其他影响的推行,因此恐怕只要连续调查询以优化性能。对查询中寓的
XPath 表达式进行双重建模后,可以另行重试它,如下所示:

SELECT count(*)
FROM oe.purchaseorder, XMLTable(
'for $i in /PurchaseOrder
where $i/User = "CJOHNSON"
return $i/User'
PASSING OBJECT_VALUE) ptab;
这次,输出应如下所示: 
COUNT(*)
----------
9
Execution Plan
---------------------------------------------------
Plan hash value: 3411896580
---------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 29 | 7 (0) | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 29 | | |
| 2 | NESTED LOOPS | | 1 | 29 | 7 (0) | 00:00:01 |
| 3 | FAST DUAL | | 1 | | 2 (0) | 00:00:01 |
|* 4 | TABLE ACCESS FULL | PURCHASEORDER | 1 | 29 | 5 (0) | 00:00:01 |
Predicate Information (identified by operation id):
---------------------------------------------------
4 - filter("PURCHASEORDER"."SYS_NC00022$"='CJOHNSON' AND
SYS_CHECKACL("ACLOID","OWNERID",xmltype('...

乃可望,以上显示的询问生成相同之末段结果,但它的实施计划并不相同。查看最后一个示范中的
XQuery 表达式,您可能会见注意到它迭代顶层 PurchaseOrder 元素,其中的每个
PurchaseOrder 元素都代表根据 PurchaseOrder XMLType
模式之表中的一条龙。这象征实际上更写 XQuery
表达式,以迭带基础对象表(用于存储分解的 PurchaseOrder
文档)中之实践。与查询而迭代不表示基础表中的么行之 XML
元素相比,该方法的性质再好有。

但是以某些情况下,很麻烦发现 XQuery
表达式的哪位构造将如少数查询的习性更好。这即是怎么最好于开发阶段使用调整工具的原由。

将动态变量绑定到 XQuery 表达式

外一样栽可以明显提高 XQuery
表达式执行性的艺是用绑定动态变量。使用绑定变量(而无是拿变量串联为字符串)可以使
Oracle 重用 SQL 语句,从而减少分析出并明白提高应用程序的属性。可以以
XMLQuery 和 XMLTable SQL 函数中使 PASSING 子句子以动态变量绑定到 XQuery
表达式。该技术使您得依据客户端代码中计算的参数动态生成 XML。列表 3
中的言传身教演示了哪以从 PHP 脚本执行的 XQuery 查询中以绑定变量。

列表 3:使用绑定变量

//File:BindVars.php
$user = 'hr';
$pswd = 'hr';
$db ='(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))
)
(CONNECT_DATA=(SID=orclR2)(SERVER=DEDICATED))
)';
$empno=100;
$conn = oci_connect($user, $pswd, $db);
$sql = 'SELECT XMLQuery('."'".'for $i in ora:view("employees")/ROW
where $i/EMPLOYEE_ID = $empno
return (
{$i/EMPLOYEE_ID,
$i/EMAIL,
$i/JOB_ID}
)'."'".'PASSING XMLElement("empno", :empno) AS "empno"
RETURNING CONTENT).GetStringVal() AS RESULT FROM DUAL';
$query = oci_parse($conn, $sql);
oci_bind_by_name($query, ":empno", $empno, 3);
oci_execute($query);
oci_fetch($query);
$str = oci_result($query, 'RESULT');
print $str;
?>

列表 3 中显示的脚论应十分成以下输出(注意,浏览器中或者未见面显标记):

100
SKING
AD_PRES

XQuery 与 XSLT

尽管 Oracle 在 Oracle XML DB 中提供了一个自带 XSLT
处理器,但于群景下(尤其是于处理大型文档时),XQuery 对于构建 XML
更高效。此外,XQuery 表达式通常较呢同作业设计之 XSLT
样式表还拥有可读性,并且还亮。与 XSLT 一样,XQuery 不但可用于将一个 XML
文档转换为另外一个 XML 文档,而且还只是用来将 XML
转换为其他一样栽基于文本的格式,如 HTML 或 WML。

当本文前面的询问 XMLType 数据有被,您看看了一个有关以 XQuery 将一个
XML 文档转换为另外一个 XML 文档的言传身教。具体而言,该示例使用 XQuery
表达式计算示例数据库模式 OE 的 purchaseorder
表中储存的订单的订单一共,然后为拍卖的每个订单生成了一个 OrderTotal XML
元素。实际上,您得应用 XSLT
执行同样操作。为是,您首先要创造一个采取叫 PurchaseOrder XML大红鹰葡京会娱乐 文档的
XSLT 样式表,以变对应的 OrderTotal 元素。对于这个示例,可以用列表 4
中所显示之 XSLT 样式表。

列表 4:使用 XSLT 计算小计总和 (Quantity * UnitPrice)

http://www.w3.org/1999/XSL/Transform" version="1.0">



























呢好起见,您可能要用此 XSL
样式表保存在数据库被,然后又开采用它们。例如,您可以样式表作为文件资源保存在
Oracle XML DB
信息库中。执行该操作的点子有是用样式表作为文件保留及本地文件系统中,然后下以下某个互联网协议将它移动及
XML 信息库:FTP、HTTP 或 WebDAV。假设你曾经将列表 4 中的 XSLT 样式表作为
orderTotal.xsl 保存在 /public
信息库文件夹着,现在可按以下示例所示将它们之所以作 XMLTransform SQL
函数的参数(假设你为 OE/OE 的位置登录):

SELECT XMLTRANSFORM(OBJECT_VALUE,
xdbUriType('/public/orderTotal.xsl').getXML()).GetStringVal() AS RESULT FROM
purchaseorder WHERE existsNode(OBJECT_VALUE, 
'/PurchaseOrder[User = "EABEL"]') = 1;

如上查询将处理用户 EABEL 请求的有所订单(即存储于 XMLType 的默认
PurchaseOrder 表中的订单)并将转与查询 XMLType 数据有被的 XQuery
查询同一之出口。

拿列表 4 中之 orderTotal XSLT 样式表与查询 XMLType
数据有受到之以身作则使用的 XQuery 表达式进行比,您可能会见小心到,XQuery
方法要比 XSLT 方法还享有吸引力。至少在采取 XQuery
时,您才待编写好少的代码即可取得同之末梢结出。

查询 RSS 新闻提供

鉴于 RSS 新闻提供精神上是一个托管的 XML 文件(RSS
新闻阅读器从中得到头条新闻或其他情节),因此可以像处理其他其它可以经
Web 获得的 XML
文档那样来处理它。正使你于本文前面的询问表数据源部分受所表现,可以动用
XQuery 查询任何可以透过 URL 访问的 XML。您通过 XMLTable 和 XMLQuery SQL
函数中的 PASSING 子句动态绑定所有外部 XML 数据源。以下是一个查询 RSS
新闻提供的 XQuery 示例:

SELECT XMLQuery(
'for $i in $h//channel
return;

{$i/lastBuildDate}

{for $j in $h//item
where ora:contains($j, "PHP")
return  {($j/title, $j/link)}}

'
PASSING xmlparse (document httpuritype
('http://www.oracle.com/technology/syndication/rss_otn_news.xml').getCLOB()) as "h"
RETURNING CONTENT).getStringVal() as RESULT FROM DUAL;

该 XQuery 应生成一个 XML 文档,其中蕴蓄 Oracle 技术网 (OTN) 最近通告的和
PHP 技术有关的头条新闻列表。所好成的 XML 文档可能如下所示:

Tue, 01 Nov 2005 19:37:42 GMT


http://www.oracle.com/technology/xe


http://www.oracle.com/technology/pub/articles/oracle_php_cookbook


http://www.oracle.com/technology/tech/php/zendcore/index.html

然而以开实际应用程序时,您将异常可能要 XQuery 表达式直接生成 HTML
标记,而无是只转移一个假设达到所展示之 XML
文档。这样,您就可以构建一个又灵敏、可维护性更胜似的应用程序,原因是于这种情形下,所有
RSS 处理(从提取必要之数码及以它包裹在 HTML
标记中)都用变至数据库。这如果你不用编写负责 RSS
处理的应用程序代码。实际上就意味你不要在诸如 RSS
新闻提供的组织都转的图景下修改应用程序代码。相反,您才待修改用于 RSS
处理的 XQuery 表达式。

总结

汝曾当本文了解及,XQuery
是一个综合的查询语言,它提供了同种用于查询、构建和换 XML
数据的快捷方法。尽管 Oracle XQuery 实施而您可操作任何可以为此 XML
表示的数据(无论她存储在数据库被、位于网站及或存储于文件系统中),但拿拍卖的数码移动及数据库被尽是一个对的呼声。对于数据库被存储的多寡,Oracle
XML DB(对 XPath
重写以同样机制)只能眼看优化处理那些因以下数据构建的 XQuery
表达式:这些多少包括关系数据、对象-关系数据或利用结构化(对象-关系)存储技术存储的因
XML 模式的 XMLType 数据。

(责任编辑:铭铭)

原文:Oracle
XQuery查询、构建与转换XML

返回数据库首页

相关文章

admin

网站地图xml地图