营造和调换XML,Oracle编程入门非凡

Oracle 九i产品扶助文书档案:

在 Oracle 数据库 10g 第 2 版中,Oracle
引进了1个与该数据库集成的专职能自带 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 数据库 拾g 第 二版在此之前的版本中实现此职务,经常供给利用 SQL/XML 生成函数,如
XMLElement、XMLForest 和 XMLAgg()。在 Oracle 数据库 十 g 第 2版中,XQuery 将比那几个函数更为高效。具体来讲,在 XQuery 表明式内部选取ora:view XQuery 函数,您能够查询现存的关系表或视图以及及时创设XML,从而不必经过关全面据显式创设 XML 视图。列表 一 中的 PL/SQL
代码演示了怎么运用 ora:view 基于示例数据库方式 HHaval的暗许职员和工人涉嫌表中贮存的数码创设 XML 文书档案。

Sample Schemas的目录:

列表 壹:使用 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 在此间将其看做参数)来讲,请小心嵌套的 FLWOKoleos表明式中动用的 ora:view XQuery 函数。在该示例中,ora:view
获取三个输入参数,即“H奥德赛”和“employees”,它们提示该函数查询属于 H途睿欧数据库方式的职员和工人表。因而,ora:view 将回来一个代表 H途锐.employees
表行的职工 XML
文档连串。但为了节省结果文书档案中的空间,只将前七个职工记录传递给结果种类。那是通过在
FLWO宝马7系 表达式的 where 子句中钦赐 $i/EMPLOYEE_ID <= 102
而落实的。请小心 FLWOSportage 表明式的 return 子句中采纳的 xs:string()
xs:integer() XQuery 类型表明式。实际上,此处使用的那四个 XQuery
表明式不止将 XML
节点值调换为对应的门类,而且还将提取这么些节点值。随后,生成的职员和工人 XML
文档作为 employees.xml 保存到事先在列表 一 中另2个 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
玖i的产出,又引入了斩新的1组示例方式,它们的靶子是扩展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情势能够提供部分示例表以及数据,来体现数据库的一些特点。它是三个相当轻松的形式,如图肆-一数据结构图所示(通过PowerDesign逆向工程转变为数据库模型)。

图四-1 SCOTT方式数据结构图

 图片 1

何以要将这么些情势命名叫SCOTT呢?SCOTT/TIGE途胜是Oracle版本一、二和3时期的Oracle数据库的早先时代用户名/密码组合。SCOTT是指Oracle公司的泰斗程序猿BruceScott。当然,TIGELacrosse是布Russ养的猫的名字。

SCOTT形式中所展现的数据库性子常常被感觉是诸多关周详据库产品中的首要特征。借使想要真实地呈现Oracle数据库的功能,就要强化那么些示例!

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

EABEL-20021009123338324PDT
1328.05


EABEL-20021009123335791PDT
2067.15


EABEL-20021009123336251PDT
289.6


EABEL-20021009123336382PDT
928.92

四.贰 Oracle 九i示例格局

Oracle技巧能够采取于种种分化的条件中。技能消除方案的五个使用极端情形是,高速在线事务处理和数据库酒店。就算用户能够行使三个情势,展现什么在同1的表中实今后线事务管理和数据旅馆。不过用户毫无也许选拔这种措施实现实用的消除方案。大家在近期的产业界中时时能够窥见,为了消除实际世界中的分裂总计需要,常常在独立的数据库实例中会存在区别的方式,或然在网络上会有多量布满式数据库。新的Oracle
玖i示例格局模型极好地对那几个情景建立模型。

Oracle
玖i示例格局试图模型化2个有血有肉世界中兼有一多种标准业务部门的行销共青团和少先队。那么些分化的单位全数差异的音信技能必要,每3个演示方式都应用了分歧的Oracle技艺来减轻它们分别的主题素材。其它,各类情势设计方案都针对一定的技艺用户。这一个方式如下:

  • HQashqai——人力财富。
  • OE——订单输入。
  • PM——产品媒体。产品媒体在数据库中累积了商场类别产品的相关多媒体内容,能够用来在Web上揭橥以及打字与印刷。PM利用了Oracle
    Intermedia,它非常规划用来拍卖公布音频、摄像以及可视数据的多媒体领域。别的,PM也屡次地使用了LOB列类型。
  • QS——队列运送。运送部门担负记录集团向客户拓展的出品运载情形,并且使用五个方式来实现那项专门的学问。QS、QS_ES、QS_WS、QS_OS、QS_CB和QS_CS构成了队列运送形式的成团。
  • SH——发售历史。

要获得同等的终极结出,能够改用 XMLQuery 函数。但假若将上多个演示中使用的
XQuery 表明式参数字传送递给 XMLQuery(如下所示):

四.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;

壹. 人力能源

人力能源方式,只怕H牧马人情势,负担管理部门、雇员、工作以及薪给新闻。图四-二出示了H途睿欧方式的详尽数据结构图示。

图片 2

则 XQuery 表明式重返的空体系将与 purchaseorder
表联接,从而包罗在查询计算果聚焦。实际上,那象征输出将不唯有含有为用户
EABEL 请求的订单生成的 OrderTotal 成分,而且还包蕴为 purchaseorder
表中蕴藏的兼具别的订单生成的空行(暗中同意情状下,purchaseorder 表包括 13二行)。从结果聚焦拔除空行的主意之1是在 SELECT 语句的 WHERE 子句中动用
existsNode SQL 函数,而不是在 XQuery 表达式中选用 WHERE 子句,如下所示:

2. 订单输入

订单输入(Order
Entry)情势,也许OE形式,能够用来治本集团从事商务活动的逐条路子中的客户、贩卖订单以及产品仓库储存。

图4-三详尽描写了OE情势的数据结构。就如大家原先领会的,与人力能源形式比较,订单输入情势特别复杂。

图片 3

图四-叁 OE情势数据结构

OE情势会记录产品仓库储存。我们将会蕴藏任性内定酒店中钦赐产品的数额。在信用合作社中会有两个宾馆,所以要运用地点标识符提出其地理区域。在WAREHOUSES表中还会有一个Oracle
Spatial列,它为大家提供了选拔Oracle Spatial空间本领的钥匙。

Oracle Spatial是在数据库中帮忙地点数据和地理数据的技术。

在OE形式中,供给顺便提供谈到四个数据库对象模型:

  • CUST_ADDRESS_TYP。那是四个在CUSTOMELX570S表中运用的指标类型。它包蕴了重重与客户地址有关的习性。

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。那是多个VA中华VCHA君越二(25)的VACRUISERRAY。那么些VARAV4RAY在CUSTOME讴歌MDXS表中作为单身的列存款和储蓄,能够用于存款和储蓄最多多少个电话号码。

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;

三. 出品媒体

产品媒体(Product
Media)格局,大概PM格局,用于管理描述公司出品的多媒体数据。录像、音频和图像那样的在线媒体都足以随输出的传播媒介数据类型存款和储蓄在数据库中。那是大家要极其研讨的格局之壹,它器重于多媒体内容,以及Oracle
Intermedia所提供的意义。

注意:

Oracle Intermedia是Oracle数据库匡助多媒体内容类型的零件。

除了Intermedia数据存储以外,PM格局还专门重视LOB列类型的运用来储存数据。

出品媒人体模型式是Oracle 九i使用名叫Oracle
Intermedia的Oracle本事消除具体世界商务必要的奇妙示例。比如,我们虚构的百货店就能够储存多媒体数据或然输出多媒体数据。因此,产品媒人体模型式中的示例能够成功如下职业:

  • 为Oracle中应用Web发表的内容存款和储蓄缩略图和完全尺寸的图像。
  • 在Oracle中积存音频剪辑。
  • 在Oracle中存款和储蓄录像剪辑。
  • 对图像类型实行处理,以便调换到与Web包容的图像类型

运用Oracle
Intermedia,一些业已很难落到实处的职务就变得相对简便易行。图四-四表示为产品媒人体模型式,以及它对订单输入表PRODUCT_INFORMATION的引用。

图片 4

图4-四 PM形式数据结构

PRINT_MEDIA表具备3个目标类型(ADHEADE昂科雷_TYP),以及在表的各种记录中存款和储蓄的指标嵌套表(TEXTDOC_TAB)。

ORDSYS.ORD__列都以1个Intermedia对象类型。这个Intermedia对象类型不仅仅能够积累图像、音频、摄像那样的2进制数据;还能积累各种与多媒体类型有关的元数据。

SQL> desc ordsys.ordimage;

如上查询与本有的起头的 XMLTable 示例生成同样的出口。

四. 行列运送

我们的虚拟公司想要使用新闻系统,以福利在线客户拓展自助订货。当客户发轫化订货的时候,系统就须求树立订单,向客户提供账单,并且要保险能够依据客户的岗位,通过适当的地点发送订货。

QS_CS方式有贰个名叫O福特ExplorerDER_STATUS_TABLE的表,能够储存订单状态。那是在全路队列运送情势安装进度中头一无二建立表(除了通过高等队列API创立的队列表以外)。我们不会显得与表有关的数据结构图,而是要研讨为队列运送格局所确立的行列系统中的音讯流程。

图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 数据

五. 发售历史

近日商务境遇中的集团壹度意识,除非大家能够选取1种有意义并且即时的不二等秘书籍,依据音讯变越来越准确的决定报告,不然世界上的全部发卖新闻都是毫无价值的。决策支持(decision
support)正是用来叙述在开始展览裁决的历程中国国投息本领使用的术语。

出售历史方式是二个古板数据仓库的言传身教。表会依照正方形方式(star
schema)设计开展公司,在这种方法下,会有二个大的SALES表位于宗旨,SALES表的外界还有局地小的查询表,可能维数(dimension)表。SALES表日常会有雅量的数额(全部的行销实时),而维数表相对于SALES表来说会比十分小。

图四-陆的数据结构图体现了出卖历史形式:

图片 6

图四-6 发售历史格局数据结构

为访问 Oracle XML DB 音讯库中蕴藏的 XML 数据,Oracle XQuery 引进了
fn:doc 和 fn:collection XQuery 函数。使用 fn:doc,您能够查询 XML
音信库中贮存的单个 XML 文书档案,而 fn:collection
让你能够访问同壹消息库文件夹中蕴藏的多个 XML 文书档案。

四.二.贰 渐进学习模式

依据分裂的受众组织格局的艺术得以鼓励新的Oracle用户通过结构化的不二等秘书籍学习手艺。举个例子,初学者能够从人力能源起初。那能够让她纯熟关系概念、查询数据、数据库操作语言、数据库定义语言、以及一些任何基本概念。

当新Oracle用户熟练了人力财富形式之后,能够三番九次分析订单输入格局。在这么些新情势中,他将会遇上对象类型、XML帮忙、Oracle
Spatial、以及任何一些较为高等的数据库性格。

接下去,用户能够深入分析任何形式所提供的特定领域。多媒体专家能够深深学习产品媒人体模型式。设计宣布-订阅型基于信息的系统的用户能够窥见,队列运送方式在她们开首上学Oracle高档队列的时候将会极其有帮带。数据货仓的热衷者最棒去分析和掌握出卖历史方式。

正如本文在此以前(参阅使用关周到据营造 XML部分)介绍的言传身教所示范,使用
fn:doc 极度简单间接。它赢得表示音讯库文件能源 (U翼虎I) 的字符串并回到该 U奥迪Q叁I
指向的文书档案。要打听 fn:collection XQuery
函数的成效,同一文件夹中至少应该多个音讯库文件。假设已经运转了列表 第11中学的代码,则早就创设了 /public/employees 消息库文件夹并在内部存款和储蓄了
employees.xml 文件。因而,您将索要在该公文夹中足足再成立1个 XML
文件,然后工夫试用 fn:collection。列表 二 中的 PL/SQL 代码基于
SCOTT/TIGE奥迪Q5 演示数据库形式的 dept 和 emp 表存款和储蓄的关全面据构建XML,然后将转移的 XML 文书档案作为 acc_dept.xml 保存到 /public/employees
音信库文件夹。要运行列表 二 中的 PL/SQL 进程,请保管以 SCOTT/TIGE奥德赛的地位登入。

4.二.三 开采越来越多关于示例情势的内容

列表 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;
/

贰. 自解释格局

Oracle提供了壹种能够让表的持有者在数据库中存款和储蓄表只怕列的纯文本注释的不二等秘书籍。在示范形式安装时期,每一种方式都独具2个本子,可认为它们分其他表和列创建这一个注释。那足以采用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(由列表 贰 中的 PL/SQL
代码生成)和 employees.xml 文件(由列表 壹 中的代码生成)。由于那些 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
文件,以便能够通过以下 UEnclaveL 访问 empsbonus.xml 文件:

http://localhost/employees/empsbonus.xml

接下去,假诺您要求基于 empsbonus.xml
文书档案中积存的数额成立1个报表。在该报表中,您可能不只要包括列表中显得的奖金多寡以及各种职员和工人的职员和工人ID,还要包涵他/她的姓名。由此,能够率先应用以下查询生成三个新的 XML
文书档案(如果你以 H汉兰达/H纳瓦拉 的身价连接):

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 第 贰 版 (10.贰) 文书档案中《SQL\Plus
用户指南和参谋》1书中的“调治SQL\Plus”1章。以下示例演示了何等通过检查 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
格局的表中的1行。那意味着实际上海重型机器厂写 XQuery
表明式,以迭带基础对象表(用于存储分解的 PurchaseOrder
文书档案)中的行。与查询要迭代不表示基础表中的单个行的 XML
成分相比较,该措施的个性越来越好有的。

但在少数情状下,很难发掘 XQuery
表明式的哪些构造将使某个查询的性质更加好。那正是为啥最棒在开拓阶段使用调治工具的原故。

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

另一种能够显明巩固 XQuery
表达式试行质量的技艺是行使绑定动态变量。使用绑定变量(而不是将变量串联为字符串)可以使
Oracle 重用 SQL 语句,从而减弱剖判成本并刚强增加应用程序的质量。能够在
XMLQuery 和 XMLTable SQL 函数中运用 PASSING 子句将动态变量绑定到 XQuery
表明式。该手艺让你能够依据客户端代码中总结的参数动态生成 XML。列表 三中的示例演示了怎么样在从 PHP 脚本试行的 XQuery 查询中使用绑定变量。

列表 三:使用绑定变量

//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;
?>

列表 三 中显得的脚本应生成以下输出(注意,浏览器中或者不会呈现标识):

100
SKING
AD_PRES

XQuery 与 XSLT

固然 Oracle 在 Oracle XML DB 中提供了2个自带 XSLT
管理器,但在繁多气象下(特别是在拍卖大型文档时),XQuery 对于营造 XML
越来越高速。其余,XQuery 表明式日常比为同一作业设计的 XSLT
样式表更具可读性,并且更通晓。与 XSLT 同样,XQuery 不但可用来将1个 XML
文档转变为另2个 XML 文书档案,而且还可用于将 XML
转换为另一种基于文本的格式,如 HTML 或 WML。

在本文前面包车型地铁查询 XMLType 数据部分中,您看看了几个有关使用 XQuery 将三个XML 文书档案转换为另三个 XML 文书档案的身体力行。具体来讲,该示例使用 XQuery
表明式计算示例数据库形式 OE 的 purchaseorder
表中存款和储蓄的订单的订单1共,然后为管理的每一种订单生成了多少个 OrderTotal XML
成分。实际上,您能够运用 XSLT
实行一样操作。为此,您首先需求创建一个利用于 PurchaseOrder XML 文书档案的
XSLT 样式表,以浮动对应的 OrderTotal 成分。对于此示例,能够选取列表 四中所示的 XSLT 样式表。

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

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



























为便于起见,您或者要求将此 XSL
样式表保存在数据库中,然后再开端运用它。举例,您能够将样式表作为文件能源保存在
Oracle XML DB
音讯库中。实施该操作的艺术之一是将样式表作为文件保留到地面文件系统中,然后选拔以下有个别网络球协会议将它移动到
XML 音信库:FTP、HTTP 或 WebDAV。借让你曾经将列表 四 中的 XSLT 样式表作为
orderTotal.xsl 保存在 /public
音信库文件夹中,未来得以按以下示例所示将它用作 XMLTransform SQL
函数的参数(借使你以 OE/OE 的地位登6):

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
查询同1的出口。

将列表 4 中的 orderTotal XSLT 样式表与查询 XMLType
数据部分中的示例使用的 XQuery 表明式举行相比,您可能会小心到,XQuery
方法要比 XSLT 方法更具魅力。至少在行使 XQuery
时,您只需编写十分少的代码即可获得同样的终极结果。

询问 奔驰M级SS 信息提供

是因为 途胜SS 新闻提供精神上是多个托管的 XML 文件(BMWX5SS
音讯阅读器从中获得头条音信或其余内容),由此得以像处理任何别的能够透过
Web 获得的 XML
文书档案那样来拍卖它。正如您在本文前边的询问外部数据源部分中所见,能够运用
XQuery 查询别的能够经过 UTiguanL 访问的 XML。您通过 XMLTable 和 XMLQuery SQL
函数中的 PASSING 子句动态绑定全体外部 XML 数据源。以下是3个询问 奇骏SS
新闻提供的 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 应生成2个 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
标志,而不是仅仅转移3个如上所示的 XML
文书档案。那样,您便足以创设二个越来越灵活、可维护性越来越高的应用程序,原因是在这种状态下,全数HighlanderSS 管理(从提取供给的数码到将它包裹在 HTML
标识中)都将退换来数据库。那使您不要编写担任 哈弗SS
管理的应用程序代码。实际上那表示你不用在举例 OdysseySS
信息提供的布局早已改成的景况下修改应用程序代码。相反,您只需修改用于 TiggoSS
管理的 XQuery 表达式。

总结

你曾经在本文明白到,XQuery
是3个综合的询问语言,它提供了1种用于查询、营造和转换 XML
数据的相当慢方法。尽管 Oracle XQuery 实践让你能够操作任何能够用 XML
表示的数量(无论它存款和储蓄在数据库中、位于网址上大概存款和储蓄在文件系统中),但将拍卖的数码移动到数据库中始终是一个科学的意见。对于数据库中存款和储蓄的数额,Oracle
XML DB(对 XPath
重写使用同样机制)只好眼看优化管理那3个基于以下数据营造的 XQuery
表明式:这一个数量包涵关周到据、对象-关周详据或选取结构化(对象-关系)存款和储蓄本事存款和储蓄的依据XML 形式的 XMLType 数据。

(主要编辑:铭铭)

原文:Oracle
XQuery查询、构建和调换XML

回去数据库首页