使用 Oracle XML DB 存储、查询、转换和访问 XML 和关系数据
使用 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 索引具有以下优势:
- XMLIndex 索引可用于 SQL/XML 函数 XMLExists()、XMLTable() 和 XMLQuery(),而且它在查询的任何部分都有效;它并不限于用在 WHERE 子句中。这与您可能用于 XML 数据的其他任何索引的情况都不同。
- XMLIndex 因此可提高对 SELECT 列表数据和 FROM 列表数据的访问速度,尤其是可以使其用于 XML 片段提取。基于函数的索引和 CTXXPath 索引
- 您无需预先了解将在查询中使用的 XPath 表达式。XMLIndex 完全是通用的,而基于函数的索引则不同。
- 可将 XMLIndex 索引用于基于 XML 模式或非基于模式的数据。它可用于二进制 XML 和非结构化存储模型。B 树索引仅适用于以对象关系方式存储(结构化存储)的基于模式的数据;它对于存储在二进制 XML 或 CLOB 实例中的基于 XML 模式的数据效率低下。
- 可使用 XMLIndex 索引通过 XPath 表达式进行搜索,这些表达式的目标是集合(即文档中出现多次的节点)。对于函数索引则不然。
Oracle 数据库自带的 XQuery: 由于 XQuery 目前是一个 W3C 标准,IT 社区已经开始接受 XML 和 XQuery 的商业使用。作为商业数据库技术的创新领导者,Oracle 数据库 11g 提供了完善的自带 XQuery 引擎,该引擎与与传统的 Oracle 数据库服务器进行。在 SQL 方面,SQL/XML 标准定义了一种将 XML 封装在 SQL 中并使用 XQuery 集成 XML 的查询的方法。通过引入新的 SQL 函数,即将完成这项工作:XMLQuery、XMLTable、XMLExists 和 XMLCast(使用 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 并确保将 OE、HR 用户解除锁定。
|
| 2. |
设置环境变量来连接 Oracle 数据库 11g。 |
| 3. |
将 xmldb_trg.zip 文件下载并解压缩到您的工作目录中(即 wkdir)
|
前提条件的附加注释:
如果您在安装 Oracle 数据库 11g 过程中未对 OE 和 HR 解除锁定,执行以下操作:
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_HOME/lib 添加到 LD_LIBRARY_PATH 环境变量
例如,如果您的 ORACLE_HOME 为 $ORACLE_BASE/product/11.1.0/db_1 且JAVA_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 表,并使用从 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 参数。
| 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 的性能。在本部分中,您将在对象关系存储上创建 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 通过视图从 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 图标。

|
返回主题列表
可使用 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 表上使用关系视图 |
返回主题列表
将鼠标置于该图标上可以隐藏所有的屏幕截图。
|