执行原地 XML 模式演变

本教程介绍如何对 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 语言、原地 XML 模式演变、数据库自带的 Web 服务、高性能 XML 发布、XML DB 信息库,以及版本控制和访问控制。本教程介绍原地 XML 模式演变以及如何使用 Oracle XML DB Web 服务实现面向服务的体系结构。

模式演变

在 Oracle XML DB 中使用 XML 模式的开发人员面临的一个主要挑战是,如何处理 XML 文档内容或结构的更改。在一些环境中,由于出现了新的法规、内部需求或外部机会,可能需要频繁地进行更改或者进行大量的更改。例如,可能需要向 XML 模式添加新的元素或属性、修改某个数据类型,或者放松或收紧某些最小和最大出现次数的要求。

在这些情况下,您需要“演变”XML 模式以满足新的要求,同时任何现有的实例文档(数据)继续有效(或者可以变为有效),并使任何现有的应用程序可以继续运行。

如果您并不关心任何现有的文档,您当然可以完全丢弃与 XML 模式相关的 XMLType 表、删除旧的 XML 模式,并在同一 URL 中注册新的 XML 模式。但在大多数情况下,您需要保留现有的文档,可能要对它们进行转换以适应新的 XML 模式。

Oracle XML DB 支持两种模式演变。每种方法都有其自己的 PL/SQL 过程:DBMS_XMLSCHEMA.copyEvolve 用于基于复制的演变,DBMS_XMLSCHEMA.inPlaceEvolve 用于原地演变,Oracle 数据库 11g 版本中引入了原地演变。

原地模式演变

原地 XML 模式演变无需复制、删除和重新插入现有的数据即可对 XML 模式进行更改。因此,原地演变要比基于复制的演变快得多。通常,如果不更改存储模型或者更改不会使现有文档无效(即,现有文档符合新的模式或者可以变得符合新的模式),则允许使用原地演变。

原地 XML 模式演变通过应用在 diffXML 文档中指定的更改构建一个新版的 XML 模式,验证这个新的 XML 模式(根据 XML 模式的 XML 模式),构建 DDL 语句以演变用于存储与 XML 模式相关的 XML 实例文档的磁盘结构,执行这些 DDL 语句,并按这些语句的顺序使用新版的 XML 模式替换旧版的 XML 模式。

返回主题列表

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

1.

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

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

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

:如果您使用的是 Oracle JDeveloper 的早期版本,屏幕截图可能稍有不同。

前提条件的附加注释

如果您在安装 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 IDENTIFIED BY HR ACCOUNT UNLOCK;
ALTER USER OE IDENTIFIED BY OE ACCOUNT UNLOCK;
GRANT DBA to OE, HR;
GRANT SELECT_CATALOG_ROLE TO OE;

必须将 HTTP 端口设置为 8080。打开一个终端窗口并执行以下语句。

sqlplus sys/oracle as sysdba;
exec dbms_xdb.sethttpport('8080');

如果已经完成了使用 Oracle XML DB 存储、查询和访问 XML 和关系数据 OBE,则无需再次将 HTTP 端口设置为 8080。

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

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

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

例如,如果您的 ORACLE_HOME$ORACLE_BASE/product/11.1.0/db_1,确保您的 .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

PATH=$ORACLE_HOME/bin:$PATH

export PATH
export ORACLE_BASE ORACLE_HOME ORACLE_SID LD_LIBRARY_PATH

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

./.bash_profile

返回主题列表

使用 DBMS_XMLSCHEMA.inPlaceEvolve 过程执行原地 XML 模式演变。使用该过程,您可以通过指定一个 XML 模式差异文档来确定要对现有的 XML 模式进行的更改。

执行下列任务:

启动 SQL Developer
使用原地 XML 模式演变

返回主题列表

启动 SQL Developer

在本教程中,您使用 SQL Developer 工具。创建数据库连接后,在 SQL Developer 中设置自动跟踪参数和脚本路径引用。执行以下步骤:

1.

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

cd /u01/app/oracle/product/11.1.0/db_1/sqldeveloper
chmod u+x sqldeveloper.sh

sh sqldeveloper.sh


2.

在 SQL Developer 中,必须以 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.

设置自动跟踪参数。执行以下步骤:

a.转至 Tools > Preferences

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

c.在 Preferences 窗口中,确保选择以下复选框。然后单击 OK

Object_Name
Cost
Cardinality

4.

要使用 @ 语法,您可以在 SQL Developer 中设置脚本路径引用。执行以下步骤:

a.选择 Tools > Preferences > Database > Worksheet Parameters。然后单击 Browse

b.浏览到包含 SQL 脚本的工作目录的位置。然后单击 Open

c 在 Preferences 窗口中,验证 Select default path to look for scripts 域中的脚本路径。单击 OK

在上一部分中,您学习了如何连接到 SQL Developer、设置自动跟踪参数和设置脚本路径引用。

返回主题

使用原地 XML 模式演变

1.

从现有版本创建新版 XML 模式。执行 createSchemaV2.sql 脚本。

@createSchemaV2.sql

declare
new_schema xmltype;
res boolean;
begin
if (dbms_xdb.existsResource('/home/OE/purchaseOrder.v2.xsd')) then
dbms_xdb.deleteResource('/home/OE/purchaseOrder.v2.xsd');
end if;
select appendChildXML (xdbUriType('/home/OE/purchaseOrder.xsd').getXML(),
'/xs:schema/xs:complexType[@name="LineItemType"]/xs:sequence',
xmltype(''),
'xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb"')
into new_schema from dual;
res := dbms_xdb.createResource('/home/OE/purchaseOrder.v2.xsd',new_schema);
commit;

end;
/

要在 SQL Developer 中执行 SQL 脚本,您可以使用 @ 语法。然后,单击 Run Script 或按 [F5]。

或者,在 Enter SQL Statement 框中右键单击以打开该文件。然后,单击 Run Script 或按 [F5]。


2.

插入符合新版 XML 模式的新 XML 文档。执行 insertNewXMLV2.sql 脚本。在脚本输出窗格中查看错误。

@insertNewXMLV2.sql

declare
new_xml xmltype;
res boolean;
begin
select column_value into new_xml
from xmltable('for $i in ora:view("PURCHASEORDER")
where $i/PurchaseOrder/Reference = "SBELL-2002100912333601PDT"
return $i');
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="1"]',
xmltype('Box'))
into new_xml from dual;
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="2"]',
xmltype('Carton'))
into new_xml from dual;
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="3"]',
xmltype('Case'))
into new_xml from dual;
select updateXML (new_xml,
'/PurchaseOrder/Reference/text()',
'SBELL-2002100912333601PDT-V2')
into new_xml from dual;
insert into PURCHASEORDER values new_xml;

commit;

end;
/

3.

现在,执行原地 XML 模式演变。执行 evolveSchema.sql

@evolveSchema.sql

set timing on
declare
schemaDiff XMLType;
res boolean;
begin
select xmlDiff
(
xdburitype('/home/OE/purchaseOrder.xsd').getXML(),
xdburitype('/home/OE/purchaseOrder.v2.xsd').getXML()
)
into schemaDiff
from dual;

if (dbms_xdb.existsResource('/home/OE/poSchemaDiff.xml')) then
dbms_xdb.deleteResource('/home/OE/poSchemaDiff.xml');
end if;

res := dbms_xdb.createResource('/home/OE/poSchemaDiff.xml',schemaDiff);

dbms_xmlschema.inPlaceEvolve('http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd',
schemaDiff, 1);
end;
/

4.

尝试再次插入符合新版 XML 模式的新 XML 文档。执行 insertNewXMLV2.sql 脚本。注意,这次没有任何错误。

@insertNewXMLV2.sql

declare
new_xml xmltype;
res boolean;
begin
select column_value into new_xml
from xmltable('for $i in ora:view("PURCHASEORDER")
where $i/PurchaseOrder/Reference = "SBELL-2002100912333601PDT"
return $i');
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="1"]',
xmltype('Box'))
into new_xml from dual;
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="2"]',
xmltype('Carton'))
into new_xml from dual;
select appendChildXML (new_xml,
'/PurchaseOrder/LineItems/LineItem[@ItemNumber="3"]',
xmltype('Case'))
into new_xml from dual;
select updateXML (new_xml,
'/PurchaseOrder/Reference/text()',
'SBELL-2002100912333601PDT-V2')
into new_xml from dual;
insert into PURCHASEORDER values new_xml;

commit;

end;
/

5.

验证新的 XML 文档已经成功插入。执行 verifyEvol.sql

@verifyEvol.sql

select column_value from
XMLTable ('for $i in ora:view("PURCHASEORDER") where exists($i/PurchaseOrder/LineItems/LineItem/Unit) return $i/PurchaseOrder/Reference');


返回主题

返回主题列表

在本教程中,您学习了如何使用原地 XML 模式演变。

返回主题列表

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