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

返回数据库首页

发表评论

电子邮件地址不会被公开。 必填项已用*标注