网站首页/技术开发列表/内容

Oracle XQuery查询、构建与转换XML(4)

技术开发2024-04-12阅读
将动态变量绑定到 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 表中存储的订单的订单总计,然后为处理的每个订单生成了一个 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 时,您只需编写很少的代码即可获得相同的最终结果。

查询 RSS 新闻提供

由于 RSS 新闻提供本质上是一个托管的 XML 文件(RSS 新闻阅读器从中获取头条新闻或其他内容),因此可以像处理任何其他可以通过 Web 获得的 XML 文档那样来处理它。正如您在本文前面的查询外部数据源部分中所见,可以使用 XQuery 查询任何可以通过 URL 访问的 XML。您通过 XMLTable 和 XMLQuery SQL 函数中的 PASSING 子句动态绑定所有外部 XML 数据源。以下是一个查询 RSS 新闻提供的 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 应生成一个 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 标记,而不是仅仅生成一个如上所示的 XML 文档。这样,您便可以构建一个更灵活、可维护性更高的应用程序,原因是在这种情况下,所有 RSS 处理(从提取必要的数据到将它包装在 HTML 标记中)都将转移到数据库。这使您不必编写负责 RSS 处理的应用程序代码。实际上这意味着您不必在诸如 RSS 新闻提供的结构已经更改的情况下修改应用程序代码。相反,您只需修改用于 RSS 处理的 XQuery 表达式。

总结

您已经在本文了解到,XQuery 是一个综合的查询语言,它提供了一种用于查询、构建和转换 XML 数据的高效方法。尽管 Oracle XQuery 实施使您可以操作任何可以用 XML 表示的数据(无论它存储在数据库中、位于网站上还是存储在文件系统中),但将处理的数据移动到数据库中始终是一个不错的主意。对于数据库中存储的数据,Oracle XML DB(对 XPath 重写使用同一机制)只能显著优化处理那些基于以下数据构建的 XQuery 表达式:这些数据包括关系数据、对象-关系数据或使用结构化(对象-关系)存储技术存储的基于 XML 模式的 XMLType 数据。

相关阅读