但在拍卖数据库中存储的结构化数据方面,Sample Schemas的文档(示例形式的表及介绍)

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公司的终南山北斗程序员BruceScott。当然,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(东边)、韦斯特(西边)或者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

回去数据库首页

相关文章