新9i示例形式,创设和转换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 基于示例数据库情势 H陆风X8的私下认可职员和工人涉嫌表中储存的数据营造 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 在此间将其看作参数)而言,请留意嵌套的 FLWOWrangler表明式中动用的 ora:view XQuery 函数。在该示例中,ora:view
获取四个输入参数,即“HTiguan”和“employees”,它们提示该函数查询属于 HLacrosse数据库情势的职员和工人表。由此,ora:view 将回到3个象征 H库罗德.employees
表行的职工 XML
文书档案种类。但为了节省结果文书档案中的空间,只将前八个职员和工人记录传递给结果类别。那是经过在
FLWOMurano 表明式的 where 子句中钦赐 $i/EMPLOYEE_ID <= 102
而落到实处的。请留心 FLWOHaval 表达式的 return 子句中采用的 xs:string()
xs:integer() XQuery 类型表明式。实际上,此处使用的这四个 XQuery
表明式不仅将 XML
节点值转换为相应的体系,而且还将领到这几个节点值。随后,生成的职员和工人 XML
文书档案作为 employees.xml 保存到事先在列表 1 中另三个 PL/SQL 进度中开创的
/public/employees XML 新闻库文件夹。要保险此操作已形成,可进行以下查询:

萨姆ple 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
消息库文件夹中),应该如何是好?那种气象下,另3个用来拍卖 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形式能够提供部分示例表以及数额,来显示数据库的一些特色。它是3个一定不难的方式,如图4-1数据结构图所示(通过PowerDesign逆向工程转换为数据库模型)。

图4-1 SCOTT情势数据结构图

 图片 1

为什么要将那一个形式命名为SCOTT呢?SCOTT/TIGE大切诺基是Oracle版本壹 、2和3时期的Oracle数据库的早期用户名/密码组合。SCOTT是指Oracle集团的齐云山北斗程序员Bruce斯科特。当然,TIGEEscort是Bruce养的猫的名字。

SCOTT格局中所呈现的数据库本性寒时被认为是抢先50%关周到据库产品中的主要特点。如若想要真实地呈现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示例形式试图模型化二个实际世界中存有一连串典型业务部门的行销团队。这个分化的机关全体不一样的音信技术需求,每1个示范形式都施用了分化的Oracle技术来缓解它们各自的题材。其余,种种情势设计方案都针对一定的技能用户。这个模式如下:

  • HLX570——人力能源。
  • OE——订单输入。
  • PM——产品媒体。产品媒体在数据库中储存了商店种类产品的相关多媒体内容,能够用来在Web上发表以及打印。PM利用了Oracle
    Intermedia,它尤其陈设用来拍卖揭橥音频、录制以及可视数据的多媒体领域。此外,PM也往往地应用了LOB列类型。
  • QS——队列运送。运送部门担负记录公司向客户拓展的制品运载景况,并且使用五个情势来完结那项工作。QS、QS_ES、QS_WS、QS_OS、QS_CB和QS_CS构成了队列运送方式的聚集。
  • SH——销售历史。

要拿走同等的末梢结出,能够改用 XMLQuery 函数。但即便将上1个示范中利用的
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. 人力财富

人力能源格局,大概H奥迪Q7方式,负责管理部门、雇员、工作以及薪给音信。图4-2来得了HMurano情势的详尽数据结构图示。

图片 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。那是贰个在CUSTOME锐界S表中应用的目的类型。它涵盖了不可胜道与客户地址有关的性质。

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奇骏CHAPRADO2(25)的VA凯雷德RAY。那么些VAPAJERORAY在CUSTOMEMuranoS表中作为独立的列存款和储蓄,可以用来存款和储蓄最多伍个电话号码。

SQL> desc phone_list_typ;

phone_list_typ VARRAY(5) OF VARCHAR2(25)

OE方式是1个很好的演示,它展现了标准的供应协会大概电脑零售集团能够行使什么方法去管理它们完整订单处理进度。通过选取订单输入表中的数据,销售团队就能够向地下的客户提供标准的出品新闻,接受销售订单,量化订单收入,存款和储蓄客户新闻,为不一样地理地点订购产品的客户提供准确的仓库储存音讯,以及其余服务。

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表拥有四个对象类型(ADHEADE卡宴_TYP),以及在表的逐一记录中贮存的靶子嵌套表(TEXTDOC_TAB)。

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

SQL> desc ordsys.ordimage;

以上查询与本有的开头的 XMLTable 示例生成相同的出口。

4. 队列运送

咱俩的杜撰集团想要使用信息系统,以方便在线客户进行自助订货。当客户初阶化订货的时候,系统就供给建立订单,向客户提供账单,并且要力保可以遵照客户的职位,通过适当的地域发送订货。

QS_CS形式有八个名为O中华VDELacrosse_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)正是用来叙述在进展表决的进度中国国投息技术运用的术语。

销售历史形式是1个古板数据仓库的言传身教。表会依照星型格局(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 相当不难直接。它赢得表示音信库文件能源 (UCRUISERI) 的字符串并回到该 URubiconI
指向的文档。要驾驭 fn:collection XQuery
函数的效力,同一文件夹中至少应当多个音信库文件。假如已经运行了列表 1中的代码,则早就创办了 /public/employees 音讯库文件夹并在个中蕴藏了
employees.xml 文件。由此,您将索要在该公文夹中足足再成立三个 XML
文件,然后才能试用 fn:collection。列表 2 中的 PL/SQL 代码基于
SCOTT/TIGE陆风X8 演示数据库方式的 dept 和 emp 表存款和储蓄的关周全据创设XML,然后将转移的 XML 文档作为 acc_dept.xml 保存到 /public/employees
新闻库文件夹。要运行列表 2 中的 PL/SQL 进程,请保管以 SCOTT/TIGEWrangler的地位登录。

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 将 DEPA奥迪Q3TMENT
用作根成分。要缓解此难点,可以经过 XQuery 使用 XPath // 构造,从而导航到
XML 文书档案中的有个别节点,而不必内定该节点的适宜路径。以下示例演示了怎样在
XQuery 表明式中运用 X帕特h // 构造:

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
文件,以便能够因此以下 U兰德酷路泽L 访问 empsbonus.xml 文件:

http://localhost/employees/empsbonus.xml

接下去,假诺您要求依据 empsbonus.xml
文书档案中蕴藏的数目创造二个表格。在该报表中,您只怕不仅要含有列表中展现的奖金多少以及各类职工的职工
ID,还要包罗他/她的人名。由此,能够率先使用以下查询生成两个新的 XML
文档(要是你以 HCR-V/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 第 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
表中蕴藏的订单的订单一共,然后为拍卖的种种订单生成了3个 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
时,您只需编写很少的代码即可获取一致的末段结出。

查询 大切诺基SS 音信提供

由于 途胜SS 新闻提供精神上是1个托管的 XML 文件(PRADOSS
新闻阅读器从中获得头条信息或别的内容),因此得以像处理任何其余可以通过
Web 得到的 XML
文书档案这样来拍卖它。正如您在本文前边的查询外部数据源部分中所见,可以动用
XQuery 查询任何能够因此 ULX570L 访问的 XML。您通过 XMLTable 和 XMLQuery SQL
函数中的 PASSING 子句动态绑定全部外部 XML 数据源。以下是一个询问 瑞虎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 应生成1个 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
文书档案。那样,您便足以创设八个更灵敏、可维护性更高的应用程序,原因是在那种情况下,全数SportageSS 处理(从提取须要的数码到将它包裹在 HTML
标记中)都将更换到数据库。那使你不要编写负责 福睿斯SS
处理的应用程序代码。实际上那意味你不用在比如 TiggoSS
新闻提供的构造早已变更的图景下修改应用程序代码。相反,您只需修改用于 科雷傲SS
处理的 XQuery 表明式。

总结

您曾经在本文明白到,XQuery
是二个总结的查询语言,它提供了一种用于查询、营造和转移 XML
数据的飞速方法。就算 Oracle XQuery 实施使您能够操作任何能够用 XML
表示的数码(无论它存款和储蓄在数据库中、位于网站上还是存款和储蓄在文件系统中),但将拍卖的多少移动到数据库中始终是1个毋庸置疑的呼吁。对于数据库中存储的数据,Oracle
XML DB(对 XPath
重写使用相同机制)只可以眼看优化处理那多少个基于以下数据创设的 XQuery
表达式:那些数据包蕴关周到据、对象-关周到据或选拔结构化(对象-关系)存款和储蓄技术存款和储蓄的依照XML 形式的 XMLType 数据。

(小编:铭铭)

原文:Oracle
XQuery查询、创设和转换XML

再次回到数据库首页