Oracle 技术网

使用 Oracle XML DB 存储、查询和访问 XML 和关系数据

本教程向您介绍如何在 Oracle XML DB 中存储、查询和访问 XML 和关系数据。

大约 30 分钟。

主题

本教程包括下列主题:

将鼠标置于此图标上可以加载和查看本教程的所有屏幕截图。 (警告:因为此操作会同时加载所有屏幕截图,所以网速较慢时,响应时间可能会比较长。)

注:此外,您还可以在下列步骤中将鼠标放在每个单独的图标上,从而仅加载和查看与该步骤相关的屏幕截图。可以通过单击各个屏幕截图来将其隐藏。

概述

从 Oracle 9i 数据库第 2 版开始,Oracle XML DB 已与 Oracle 数据库无缝集成,以便为 XML 数据提供高性能的数据库自带的存储、检索和管理。使用新的 Oracle 数据库版本 11g,Oracle XML DB 实现了又一次飞跃,它通过大量丰富的新功能简化了 DBA 管理 XML 数据的任务,同时进一步支持 XML 和 SOA 应用程序开发人员。Oracle XML DB 现在支持多个数据库自带的 XML 存储模型和 XML 索引模式、SQL/XML 标准操作、W3C 标准 XQuery 数据模型和 XQuery/XPath 语言、数据库自带的 Web 服务、高性能 XML 发布、XML DB 信息库,以及版本控制和访问控制。本教程包含这些主题以及一些使用 Oracle XML DB 存储、查询、转换和访问 XML 和关系数据的关键新特性。

二进制 XML 存储模型
二进制 XML 是一个针对抽象数据类型 XMLType 的新存储模型,用以联接结构化(对象关系)和非结构化 (CLOB) 存储的现有本机存储模型。二进制 XML 存储提供比非结构化存储更高效的数据库存储、更新、索引和片段提取。它可以提供比非结构化存储更好的查询性能 — 它不会受制于 XML 分析瓶颈(它是一个分析后持久性模型)。与结构化存储类似,二进制 XML 存储了解 XML 模式数据类型并可以利用本机数据库数据类型。与非结构化存储类似,数据库插入或检索过程中无需数据转换。与结构化存储类似,二进制 XML 存储允许分段更新。由于二进制数据还可以用在数据库的外部,因此它可以作为高效的 XML 交换媒介,大多数情况下您可以从数据库卸载工作以提高整体性能。与非结构化存储类似,二进制 XML 数据按文档顺序保存。与结构化存储类似,数据和元数据可通过二进制存储在数据库级别分离,以提高效率。然而,与非结构化存储类似,二进制存储允许混合的数据和元数据,这允许实例结构产生变化。二进制 XML 存储允许非常复杂和可变的数据,这些数据在结构化存储模型中肯定会使用大量数据库表和联接。与其他 XMLType 存储模型不同的是,即使 XML 模式事先是未知的,您也可以针对基于 XML 模式的数据使用二进制存储,而且您可以将多个 XML 模式存储在同一表中并跨常见元素查询。

XMLIndex二进制 XML 和非结构化 XML 存储模型的索引:
B 树索引可以方便地用于结构化存储。它们通过直接针对基础对象来提供焦点。然而,在解决存储在二进制 XML 或 CLOB 实例中的 XML 文档的详细结构(元素和属性)时,它们通常效率低下。这是 XMLIndex 的特殊领域:二进制 XML 和非结构化存储模型。与 B 树索引(您为表示单个 XML 元素或属性的特定列定义索引)不同,XMLIndex 索引非常通用:使用 XMLIndex 的索引适用于 XML 数据所有可能的 XPath 表达式。与其他索引方法相比,XMLIndex 索引具有以下优势:

Oracle 数据库自带的 XQuery
由于 XQuery 目前是一个 W3C 标准,IT 社区已经开始接受 XML 和 XQuery 的商业使用。作为商业数据库技术的创新领导者,Oracle 数据库 11g 提供了完善的自带 XQuery 引擎,该引擎与与传统的 Oracle 数据库服务器进行。在 SQL 方面,SQL/XML 标准定义了一种将 XML 封装在 SQL 中并使用 XQuery 集成 XML 的查询的方法。通过引入新的 SQL 函数,即将完成这项工作:XMLQueryXMLTableXMLExistsXMLCast(使用 XQuery 操作 XML 和 SQL 值)。Oracle 数据库 11g 通过这些 SQL 标准函数在数据库服务器中实现了 XQuery 支持。还在 SQL*Plus 中实现了新的 XQUERY 命令,以允许用户在命令行中输入 XQuery 表达式。 通过 Oracle 数据库 11g 中 XQuery 基于标准的实现,应用程序开发人员可以使用喜好的 API(例如 JDBC、ODP.NET 和 Web 服务)来利用 Oracle 数据库 XQuery 功能。

Oracle XQuery 的好处:
通过对结构化、非结构化和二进制 XML 存储模型使用 SQL/XML XQuery 函数和索引模式,XML DB 可以使用超过基于 DOM 的 XML 查询功能评估几个数量级的性能来跨不同存储模型执行统一 XML 查询。此外,XML 查询可以无缝地与 SQL 关系查询进行合并,来处理所有查询情况。最后,Oracle XML DB 的 XML 查询功能建立在业界最好的关系型数据库基础之上,具有高度的可靠性、可用性、可伸缩性和安全性。简而言之,Oracle 数据库 11g 中的 XML DB 查询功能为通用、可伸缩、并发以及高性能的 XML 应用程序提供了最全面、最高效的功能。

返回主题列表

开始学习本教程之前,您应该先完成以下步骤:

1.

安装 Oracle 数据库 11g 并确保将 OEHR 用户解除锁定。

2. 设置环境变量来连接 Oracle 数据库 11g
3.

xmldb_trg.zip 文件下载并解压缩到您的工作目录中(即 wkdir)

前提条件的附加注释

如果您在安装 Oracle 数据库 11g 过程中未对 OEHR 解除锁定,执行以下操作:

a.打开一个终端窗口,键入以下命令:

sqlplus sys/oracle as sysdba;

b.以 sys 身份连接后,对 OE 和 HR 帐户解除锁定,然后将 dba 角色授予给 OE 和 HR。将 SELECT_CATALOG_ROLE 授予 OE。在 SQL*Plus 窗口中,键入以下命令。也可以运行 accounts.sql 脚本:

ALTER USER HR ACCOUNT UNLOCK IDENTIFIED BY HR;
ALTER USER OE ACCOUNT UNLOCK IDENTIFIED BY OE;
GRANT DBA to OE, HR;
GRANT SELECT_CATALOG_ROLE TO OE;

要设置环境变量来连接 Oracle 数据库 11g,执行以下操作

a.打开一个终端窗口,搜索 .bash_profile

b. 编辑 .bash_profile 以确保以下内容:

例如,如果您的 ORACLE_HOME$ORACLE_BASE/product/11.1.0/db_1JAVA_HOME/home/oracle/jdk1.5.0_05,确保您的 .bash_profile 包括以下项:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORACLE_HOME/lib
ORACLE_BASE=/u01/app/oracle
ORACLE_HOME=$ORACLE_BASE/product/11.1.0/db_1
ORACLE_SID=orcl
JAVA_HOME=/home/oracle/jdk1.5.0_05
PATH=$JAVA_HOME/bin:$PATH

PATH=$ORACLE_HOME/bin:$PATH

CLASSPATH=$ORACLE_HOME/jdbc/lib/ojdbc.jar:$ORACLE_HOME/jlib/orai18n.jar
export PATH
export ORACLE_BASE ORACLE_HOME ORACLE_SID JAVA_HOME LD_LIBRARY_PATH

c.对 .bash_profile 进行更改后,执行如下所示的脚本:

./.bash_profile

返回主题列表

在 Oracle 数据库 11g 随附的示例模式中,已经提供了一个 XML 模式(作为 OE 模式的一部分)。在本部分中,您将使用企业管理器查看其内容。执行以下步骤:

1.

打开浏览器,输入以下 URL:

https://<主机名>:1158/em

输入以下详细信息,接受 Connect As 的默认值。

User Name:system
Password:oracle

然后,单击 Login

2.

显示 Oracle 企业管理器 11g 数据库控制窗口。单击 Schema 选项卡。

3.

选择 XML Database 下的 Configuration 链接。

4.

输入 2100 作为 FTP Port,输入 8080 作为 HTTP Port。然后,单击 OK


5.

现在已经完成了配置设置。单击 Database

6.

转至 Schema > XML Database,选择 Resources 链接。


7.

这将显示所有资源。展开 home

8.

展开 OE - PurchaseOrders - 2002 - Apr 以显示 XML 文档列表。单击列表中的第一个 XML 文档。

9.

这将显示该文档的一般信息。要查看该文档的实际内容,单击 Display Contents

10.

这将显示文件内容。单击 Show formatted XML Content

11.

查看格式化的 XML 文档。完成操作后关闭此窗口。

12.

单击 Database

13.

转至 Schema > XML Database。然后,单击 XMLType Tables


14.

在 XMLType Tables 的 Serach 窗口中,Object Name 显示为 SYSTEM。删除 SYSTEM,然后单击 Go

15.

单击表名 PURCHASEORDER

16.

显示表定义。向下滚动查看详细信息。然后,单击 OK


17.

要注销 Oracle 企业管理器 11g,单击 Logout

返回主题列表

创建二进制 XML 表

在本部分中,您将创建一个二进制 XML 表,并使用从 PURCHASEORDER 表中选择的数据插入行。您在整个教程中使用 Oracle SQL Developer。执行以下步骤:

返回主题列表

启动 SQL Developer

执行以下步骤:

1.

打开终端窗口,转至 SQL Developer 的安装位置。然后,启动 SQL Developer。使用以下命令。

cd /u01/app/oracle/product/11.1.0/db_1/sqldeveloper
sh sqldeveloper.sh

2.

必须以 OE 用户身份创建数据库连接。执行以下步骤。

a.在 Connections 选项卡中,右键单击 Connections 并选择 New Connection

b.显示 New/Select Database Connection 窗口。输入以下详细信息细节,单击 Test 确保连接正确设置。

Connection Name:oe
UserName:oe
Password:oe
Hostname:localhost 或 <主机名>,如果您要使用远程计算机
Port:1521
SID:orcl

如果选择 Save Password 复选框,口令保存到一个 XML 文件。因此,关闭 SQL Developer 连接并再次打开后,系统不会提示您输入口令。



c.测试状态显示成功。单击 Connect

3.

设置 Autotrace 参数。执行以下步骤:

a.转至 Tools > Preferences

b.展开 Database,然后选择 Autotrace Parameters

c.确保选择以下复选框,然后单击 OK

Object_Name
Cost
Cardinality

在上一部分中,您学习了如何连接到 SQL Developer 并设置 Autotrace 参数。

返回主题

创建二进制 XML 表

1.

用二进制 XML 存储创建一个 XMLType 表,并用从 PURCHASEORDERS 表中选择的数据填充此表。运行 create_s1_bix_table.sql 脚本。执行以下步骤:

a. 右键单击 Enter SQL Statement 框并选择 Open File

b.浏览至您的工作目录位置,选择 <文件名> 文件。然后单击 Open

c.代码显示在 SQL Worksheet 的 Enter SQL Statement 框中。单击 Run Script 图标。也可以按 F5。注意,结果显示在 Script Output 窗格下。

create_s1_bix_table.sql

DROP table po_sl_bix_table purge;
/

CREATE TABLE PO_SL_BIX_TABLE OF XMLType
XMLType STORE AS BINARY XML;
/
INSERT INTO po_sl_bix_table
SELECT object_value from purchaseorder;

/

注意:在本教程中,要在 SQL Developer 中执行脚本文件,必须遵循上面的步骤 a 到 c。如果要运行鼠标指针处的单条语句,单击 Execute Statement 图标。也可以将光标移到此语句上,然后按 F9

在上面的主题中,您学习了如何用二进制 XML 存储创建一个 XMLType 表。还学习了如何向该表中填充数据。

返回主题列表

通过创建索引增强 XQuery 表达式的性能

您可以通过创建索引来增强 XQuery 的性能。在本部分中,您将在对象关系存储上创建 B 树索引并在二进制存储表上创建 XMLIndex 索引。然后,您针对对象关系和二进制 XML 表运行 SQL/XML 和 XQuery 表达式,以查看解释计划并注意到性能已经改进了。执行以下步骤:

1.

在您的 SQLDeveloper 会话中,以 OE 用户身份连接。然后,执行 createXMLIndexes 脚本。

set echo on
-- B-tree indexes for O-R storage
drop index iPurchaseOrderUser;
drop index iPurchaseOrderRef;
drop index iLineItemPartNumber;
drop index iPartNumber;
drop index iDESCRIPTION_FULL_TEXT;

-- XMLIndex indexes for binary XML storage
drop index po_sl_xmlindex_bix_ix force;
drop index po_sl_bix_text_ix;

create index iPurchaseOrderUser on PurchaseOrder
(extractValue(object_value,'/PurchaseOrder/User'))
/
create index iPurchaseOrderRef on PurchaseOrder
(extractValue(object_value,'/PurchaseOrder/Reference'))
/

create index iLineItemPartNumber on LINEITEM_TABLE
(ITEMNUMBER, PART.PART_NUMBER, NESTED_TABLE_ID) compute statistics
/
create index iPartNumber on LINEITEM_TABLE
(PART.PART_NUMBER, NESTED_TABLE_ID) compute statistics
/

-- Create XML index on the binary XML table
create index po_sl_xmlindex_bix_ix on po_sl_bix_table(object_value) indextype is xdb.xmlindex
parameters ('PATH TABLE po_sl_bix_path_table
PATH ID INDEX po_sl_bix_path_id_ix
ORDER KEY INDEX po_sl_bix_order_key_ix
VALUE INDEX po_sl_bix_value_ix')
/

-- Create a secondary text index on the VALUE column of the path table
CREATE INDEX po_sl_bix_text_ix ON po_sl_bix_path_table (VALUE) INDEXTYPE IS CTXSYS.CONTEXT
parameters ('transactional')
/

call dbms_stats.gather_table_stats(USER,'PURCHASEORDER')
/
call dbms_stats.gather_table_stats(USER,'LINEITEM_TABLE')
/
call dbms_stats.gather_table_stats(USER,'po_sl_bix_table')
/
call dbms_stats.gather_index_stats(USER,'iPurchaseOrderUser')
/
call dbms_stats.gather_index_stats(USER,'iPurchaseOrderRef')
/
call dbms_stats.gather_index_stats(USER,'iLineItemPartNumber')
/
call dbms_stats.gather_index_stats(USER,'iPartNumber')
/
call dbms_stats.gather_index_stats(USER,'po_sl_xmlindex_bix_ix')
/
call dbms_stats.gather_index_stats(USER,'po_sl_bix_text_ix')

/


2.

既然已经创建了索引,就可以查看解释计划以观察 SQL/XML、XQuery 表达式的性能。观察到解释计划获取了适用的索引。

首先,查看检查特定采购订单的查询的解释计划。在 Enter SQL Statement 框中, 执行以下步骤:

a.打开 XQuery03a文件。代码显示在 Enter SQL Statement 框中。现在,单击 Autotrace 图标。注意使用了 IPURCHASEORDERREF 索引。

XQuery03a 中的代码:
--Xquery:Review a specific purchase order

SELECT XMLQuery('/PurchaseOrder/ShippingInstructions/name' passing object_value returning content)
FROM PURCHASEORDER
WHERE XMLEXISTS('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' passing object_value)
/

b. 打开 XQuery03b 文件,点击 Autotrace 图标。注意使用了 XMLIndex 索引。

XQuery03b 中的代码:
-- Same query on a binary storage table
SELECT XMLQuery('/PurchaseOrder/ShippingInstructions/name' passing object_value returning content).getStringVal()
FROM PO_SL_BIX_TABLE
WHERE XMLEXISTS('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' passing object_value)
/

3.

查看检查所有具有特定部件 id 的采购订单的查询的执行计划。

a.打开 XQuery04a 文件。代码显示在 Enter SQL Statement 框中。现在,单击 Autotrace 图标。注意使用了 IPARTNUMBER 索引。

XQuery04a 中的代码:
--List the purchase orders References having a particular part id

SELECT XMLQuery('/PurchaseOrder/Reference' passing object_value returning content)
FROM PURCHASEORDER
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem/Part[@Id="717951002372"]' passing object_value)
/

b. 打开 XQuery04b 文件,点击 Autotrace 图标。注意使用了 XMLIndex 索引。

XQuery04b 中的代码:
--Same query on binary storage table
SELECT XMLQuery('/PurchaseOrder/Reference' passing object_value returning content).getStringVal()
FROM PO_SL_BIX_TABLE
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem/Part[@Id="717951002372"]' passing object_value)
/

4.

查看列出特定采购订单的每个条目描述的查询的执行计划。

a.打开 XQuery05a 文件。代码显示在 Enter SQL Statement 框中。现在,单击 Autotrace 图标。

XQuery05a 中的代码:
-- 1. List the description for each item on the purchase order

SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem/Description' passing object_value returning content)
FROM PURCHASEORDER
WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' passing object_value)
/

b.打开 XQuery05b 文件。代码显示在 Enter SQL Statement 框中。现在,单击 Autotrace 图标。

XQuery05b 中的代码:
--same query on binary storage table
SELECT XMLQuery('/PurchaseOrder/LineItems/LineItem/Description' passing object_value returning content).getStringVal()
FROM PO_SL_BIX_TABLE
WHERE XMLExists('/PurchaseOrder[Reference="SBELL-2002100912333601PDT"]' passing object_value)
/

5.

查看列出特定采购订单上带有包含野餐的描述的 LineItem 20 的引用的查询的执行计划。打开 XQuery06b 文件。代码显示在 Enter SQL Statement 框中。现在,单击 Autotrace 图标。

XQuery06b 中的代码:
--same query on binary storage table
SELECT XMLQuery('/PurchaseOrder/Reference' passing object_value returning content).getStringVal()
FROM PO_SL_BIX_TABLE
WHERE XMLExists('/PurchaseOrder/LineItems/LineItem[@ItemNumber=20]/Description/text()[ora:contains(.,"Picnic") > 0]' passing object_value)
/

在上面的主题中,您学习了如何在对象关系存储中创建 B 树索引以及如何在二进制 XML 表上创建 XMLIndex 索引。还学习了如何通过查看解释计划来观察 SQL/XML 和 XQuery 表达式的性能。

返回主题列表

通过 XQuery 使用 XMLType

您可以使用 XQuery 通过视图从 SQL 数据生成 XMl。执行以下步骤:

1.

首先,使用 XMLTable() SQL/XML 函数和 XQuery 表达式来根据关系表创建 XML 视图。执行以下脚本:

createXQueryView

create or replace synonym departments for hr.departments
/
create or replace synonym locations for hr.locations
/
create or replace synonym countries for hr.countries
/
create or replace synonym employees for hr.employees
/
create or replace synonym jobs for hr.jobs
/
create or replace view DEPARTMENT_XQL of xmltype
with object id
(extract(object_value, '/Department/@DepartmentId').getnumberVal())
as
select column_value from XMLTable
('for $d in ora:view("DEPARTMENTS"),
$l in ora:view("LOCATIONS"),
$c in ora:view("COUNTRIES")
where $d/ROW/LOCATION_ID = $l/ROW/LOCATION_ID
and $l/ROW/COUNTRY_ID = $c/ROW/COUNTRY_ID
return

{$d/ROW/DEPARTMENT_NAME/text()}

{$l/ROW/STREET_ADDRESS/text()}

{$l/ROW/CITY/text()}
{$l/ROW/STATE_PROVINCE/text()}
{$l/ROW/POSTAL_CODE/text()}
{$c/ROW/COUNTRY_NAME/text()}


{
for $e in ora:view("EMPLOYEES"),
$m in ora:view("EMPLOYEES"),
$j in ora:view("JOBS")
where $e/ROW/DEPARTMENT_ID = $d/ROW/DEPARTMENT_ID
and $j/ROW/JOB_ID = $e/ROW/JOB_ID
and $m/ROW/EMPLOYEE_ID = $e/ROW/MANAGER_ID
return

{$e/ROW/FIRST_NAME/text()}
{$e/ROW/LAST_NAME/text()}
{$e/ROW/EMAIL/text()}
{$e/ROW/PHONE_NUMBER/text()}
{$e/ROW/HIRE_DATE/text()}
{$j/ROW/JOB_TITLE/text()}
{$e/ROW/SALARY/text()}
{$m/ROW/LAST_NAME/text(), ", ", $m/ROW/FIRST_NAME/text()}

}

')
/

2.

现在,可以根据刚刚创建的 XML 视图来显示 XQuery。

a.执行 xqueryXQLView 脚本。

select t.column_value from department_xql x, xmltable('for $i in .
where $i/Department/EmployeeList/Employee/LastName="Grant"
return $i/Department/Name'
passing value(x)) t
/


b.查看查询的执行计划。单击 Autotrace 图标。

返回主题列表

在二进制 XML 表上使用关系视图

可使用 XMLTable() 函数创建并高效查询二进制 XML 表的关系视图。执行以下步骤:

1.

首先,使用 XMLTable() SQL/XML 函数在二进制 XML 上创建一个关系视图。执行 createXMLTableView 脚本。

create or replace view PO_MASTER_DETAIL_VIEW
as
select m.REFERENCE,m.REQUESTOR,m.USERID,m.COSTCENTER,item.*
from PO_SL_BIX_TABLE,
xmltable
('/PurchaseOrder' passing object_value
COLUMNS
REFERENCE varchar2(30) path 'Reference',
REQUESTOR varchar2(128) path 'Requestor',
USERID varchar(10) path 'User',
COSTCENTER varchar2(4) path 'CostCenter',
ITEMS xmltype path 'LineItems'
) m,
xmltable
('/LineItems/LineItem' passing m.items
COLUMNS
ITEMNO number(38) path '@ItemNumber',
DESCRIPTION varchar2(1024) path 'Description',
PARTNO varchar2(56) path 'Part/@Id',
QUANTITY number(38) path 'Part/@Quantity',
UNITPRICE number(12,2) path 'Part/@UnitPrice'
) item

/

2.

现在,可以在该关系视图上使用 SQL 查询。执行 queryXMLTableView 脚本。

select REFERENCE, ITEMNO, PARTNO, DESCRIPTION
from PO_MASTER_DETAIL_VIEW
where USERID = 'SBELL'
and PARTNO in ( '37429121726', '37429122129', '715515009058' )
/

在上面的主题中,您学习了如何创建二进制 XML 表的关系视图。还学习了如何查询关系视图。

返回主题列表

在本教程中,您学习了如何:

在企业管理器中查看 XML 模式
创建二进制 XML 表并存储数据
添加索引以提高 XQuery 表达式性能
通过 XQuery 创建 XMLType 视图
在二进制 XML 表上使用关系视图

返回主题列表

将鼠标置于该图标上可以隐藏所有的屏幕截图。