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

回去数据库首页