Sample Schemas的文档(示例模式之表及介绍)尽管 Oracle XQuery

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

归来数据库首页