欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
使用 Oracle XQuery 查詢(xún)、構建和轉換 XML

使用 Oracle XQuery 查詢(xún)、構建和轉換 XML

作者:Yuli Vasiliev

了解如何利用與 Oracle 數據庫 10g 第 2 版集成的全功能自帶 XQuery 引擎的功能。

 

本文相關(guān)下載:
Oracle 數據庫 10g 第 2 版或更高版本

2006 年 2 月發(fā)表

在 Oracle 數據庫 10g 第 2 版中,Oracle 引入了一個(gè)與該數據庫集成的全功能自帶 XQuery 引擎,該引擎可用于完成與開(kāi)發(fā)支持 XML 的應用程序相關(guān)的各種任務(wù)。XQuery 是一種用于處理 XML 數據模型的查詢(xún)語(yǔ)言,它實(shí)際上可操作任何類(lèi)型的可用 XML 表達的數據。盡管 Oracle XQuery 實(shí)施使您可以使用數據庫數據和外部數據源,但在處理數據庫中存儲的結構化數據方面,Oracle XML DB 通??梢燥@著(zhù)提高性能。

本文提供的示例不僅演示了在什么場(chǎng)合下以及如何使用 XQuery 查詢(xún)、構建和轉換 XML,而且還演示了如何監控和分析 XQuery 表達式的性能執行,從而找到更高效的方法來(lái)處理同一工作負載。

基于關(guān)系數據構建 XML

在需要的情況下(例如,向 Web 服務(wù)發(fā)送結果),您可能要基于關(guān)系數據構建 XML。要在 Oracle 數據庫 10g 第 2 版之前的版本中完成此任務(wù),通常需要使用 SQL/XML 生成函數,如 XMLElement、XMLForest 和 XMLAgg()。在 Oracle 數據庫 10 g 第 2 版中,XQuery 將比這些函數更為高效。具體而言,在 XQuery 表達式內部使用 ora:view XQuery 函數,您可以查詢(xún)現有的關(guān)系表或視圖以及即時(shí)構建 XML,從而不必通過(guò)關(guān)系數據顯式創(chuàng )建 XML 視圖。列表 1 中的 PL/SQL 代碼演示了如何使用 ora:view 基于示例數據庫模式 HR 的默認員工關(guān)系表中存儲的數據構建 XML 文檔。

列表 1:使用 ora:view 基于關(guān)系數據創(chuàng )建 XML

BEGINIF(DBMS_XDB.CREATEFOLDER(‘/public/employees‘)) THENDBMS_OUTPUT.PUT_LINE(‘Folder is created‘);ELSEDBMS_OUTPUT.PUT_LINE(‘Cannot create folder‘);END IF;COMMIT;END;/DECLAREXMLdoc XMLType;BEGINSELECT XMLQuery(‘for $j in 1return ( {for $i in ora:view("HR", "employees")/ROWwhere $i/EMPLOYEE_ID <= 102return ({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)) THENDBMS_OUTPUT.PUT_LINE(‘Resource is created‘);ELSEDBMS_OUTPUT.PUT_LINE(‘Cannot create resource‘);END IF;COMMIT;END;/

在列表 1 中的第一個(gè) PL/SQL 過(guò)程中,您只是在 XML 信息庫中創(chuàng )建了一個(gè)新文件夾。在該信息庫文件夾中,您隨后將存儲此處顯示的第二個(gè) PL/SQL 過(guò)程中創(chuàng )建的 XML 文檔。第二個(gè) PL/SQL 過(guò)程首先發(fā)出 SELECT 語(yǔ)句,該語(yǔ)句使用 XMLQuery SQL 函數基于關(guān)系數據構建 XML。對于 XQuery 表達式(XMLQuery 在此處將其用作參數)而言,請注意嵌套的 FLWOR 表達式中使用的 ora:view XQuery 函數。在該示例中,ora:view 獲取兩個(gè)輸入參數,即“HR”和“employees”,它們指示該函數查詢(xún)屬于 HR 數據庫模式的員工表。因此,ora:view 將返回一個(gè)表示 HR.employees 表行的員工 XML 文檔序列。但為了節省結果文檔中的空間,只將前三個(gè)員工記錄傳遞給結果序列。這是通過(guò)在 FLWOR 表達式的 where 子句中指定 $i/EMPLOYEE_ID <= 102 而實(shí)現的。請注意 FLWOR 表達式的 return 子句中使用的 xs:string()xs:integer() XQuery 類(lèi)型表達式。實(shí)際上,此處使用的這兩個(gè) XQuery 表達式不僅將 XML 節點(diǎn)值轉換為相應的類(lèi)型,而且還將提取這些節點(diǎn)值。隨后,生成的員工 XML 文檔作為 employees.xml 保存到之前在列表 1 中另一個(gè) PL/SQL 過(guò)程中創(chuàng )建的 /public/employees XML 信息庫文件夾。要確保此操作已完成,可執行以下查詢(xún):

SELECT XMLQuery(‘for $i in fn:doc("/public/employees/employees.xml")return;$i‘RETURNING CONTENT) AS RESULT FROM DUAL;

該查詢(xún)應生成以下輸出:

<EMPLOYEES><EMPLOYEE><EMPNO>100</EMPNO><ENAME>King</ENAME><SAL>24000</SAL></EMPLOYEE><EMPLOYEE><EMPNO>101</EMPNO><ENAME>Kochhar</ENAME><SAL>17000</SAL></EMPLOYEE><EMPLOYEE><EMPNO>102</EMPNO><ENAME>De Haan</ENAME><SAL>17000</SAL></EMPLOYEE></EMPLOYEES>

在以上 XQuery 中,fn:doc XQuery 函數用于訪(fǎng)問(wèn) Oracle XML DB 信息庫中存儲的單個(gè) XML 文檔。但如果要處理一些具有相同或相似結構的 XML 文檔(存儲在同一 XML 信息庫文件夾中),應該怎么做?這種情況下,另一個(gè)用于處理 XML 信息庫資源的 XQuery 函數(即 fn:collection)可能會(huì )派上用場(chǎng)。本文稍后將介紹幾個(gè)有關(guān)如何使用 fn:collection XQuery 函數的示例。

查詢(xún) XMLType 數據

XQuery 使您可以操作基于 XML 模式以及非基于模式的數據。以下示例演示了如何使用 XMLTable 函數從 OE 演示數據庫模式中查詢(xún)基于 PurchaseOrder XML 模式的 XMLType 表。

SELECT ttab.COLUMN_VALUE AS OrderTotal FROM purchaseorder,XMLTable(‘for $i in /PurchaseOrderwhere $i/User = "EABEL"return;<OrderTotal>{$i/Reference}<Total>{fn:sum(for $j in $i/LineItems/LineItem/Partreturn ($j/@Quantity*$j/@UnitPrice))}</Total></OrderTotal>‘PASSING OBJECT_VALUE) ttab;

在以上示例中,您在 XMLTable 函數的 PASSING 子句中使用 OBJECT_VALUE 虛擬列將 purchaseorder 表作為上下文項傳遞給此處使用的 XQuery 表達式。XQuery 表達式計算用戶(hù) EABEL 請求的每個(gè)購買(mǎi)訂單的總計,并為處理的每個(gè)訂單生成一個(gè) OrderTotal XML 元素。要訪(fǎng)問(wèn)生成的 XML,請使用 SELECT 列表中的 COLUMN_VALUE 虛擬列。最終的輸出應如下所示:

ORDERTOTAL-------------------------------------------------------------<OrderTotal><Reference>EABEL-20021009123338324PDT</Reference><Total>1328.05</Total></OrderTotal><OrderTotal><Reference>EABEL-20021009123335791PDT</Reference><Total>2067.15</Total></OrderTotal><OrderTotal><Reference>EABEL-20021009123336251PDT</Reference><Total>289.6</Total></OrderTotal><OrderTotal><Reference>EABEL-20021009123336382PDT</Reference><Total>928.92</Total></OrderTotal>

要獲得相同的最終結果,可以改用 XMLQuery 函數。但如果將上一個(gè)示例中使用的 XQuery 表達式參數傳遞給 XMLQuery(如下所示):

SELECT XMLQuery(‘for $i in /PurchaseOrderwhere $i/User eq "EABEL"return    <OrderTotal>{$i/Reference}<Total>{fn:sum(for $j in $i/LineItems/LineItem/Partreturn ($j/@Quantity*$j/@UnitPrice))}</Total></OrderTotal>‘PASSING OBJECT_VALUERETURNING CONTENT)FROM purchaseorder;

則 XQuery 表達式返回的空序列將與 purchaseorder 表聯(lián)接,從而包含在查詢(xún)總結果集中。實(shí)際上,這意味著(zhù)輸出將不僅包含為用戶(hù) EABEL 請求的訂單生成的 OrderTotal 元素,而且還包含為 purchaseorder 表中存儲的所有其他訂單生成的空行(默認情況下,purchaseorder 表包含 132 行)。從結果集中排除空行的方法之一是在 SELECT 語(yǔ)句的 WHERE 子句中使用 existsNode SQL 函數,而不是在 XQuery 表達式中使用 WHERE 子句,如下所示:

SELECT XMLQuery(‘for $i in /PurchaseOrderreturn    <OrderTotal>{$i/Reference}<Total>{fn:sum(for $j in $i/LineItems/LineItem/Partreturn ($j/@Quantity*$j/@UnitPrice))}</Total></OrderTotal>‘PASSING OBJECT_VALUERETURNING CONTENT) AS ordertotalFROM purchaseorderWHERE existsNode(OBJECT_VALUE, ‘/PurchaseOrder[User = "EABEL"]‘) = 1;

以上查詢(xún)與本部分開(kāi)頭的 XMLTable 示例生成相同的輸出。

查詢(xún) Oracle XML DB 信息庫中的 XML 數據

為訪(fǎng)問(wèn) Oracle XML DB 信息庫中存儲的 XML 數據,Oracle XQuery 引入了 fn:doc 和 fn:collection XQuery 函數。使用 fn:doc,您可以查詢(xún) XML 信息庫中存儲的單個(gè) XML 文檔,而 fn:collection 使您可以訪(fǎng)問(wèn)同一信息庫文件夾中存儲的多個(gè) XML 文檔。

正如本文之前(參閱使用關(guān)系數據構建 XML部分)介紹的示例所演示,使用 fn:doc 非常簡(jiǎn)單直接。它獲取表示信息庫文件資源 (URI) 的字符串并返回該 URI 指向的文檔。要了解 fn:collection XQuery 函數的作用,同一文件夾中至少應有兩個(gè)信息庫文件。如果已經(jīng)運行了列表 1 中的代碼,則已經(jīng)創(chuàng )建了 /public/employees 信息庫文件夾并在其中存儲了 employees.xml 文件。因此,您將需要在該文件夾中至少再創(chuàng )建一個(gè) XML 文件,然后才能試用 fn:collection。列表 2 中的 PL/SQL 代碼基于 SCOTT/TIGER 演示數據庫模式的 dept 和 emp 表存儲的關(guān)系數據構建 XML,然后將生成的 XML 文檔作為 acc_dept.xml 保存到 /public/employees 信息庫文件夾。要運行列表 2 中的 PL/SQL 過(guò)程,請確保以 SCOTT/TIGER 的身份登錄。

列表 2:基于關(guān)系數據構建 XML 并將其保存到 XML 信息庫

DECLAREXMLdoc XMLType;BEGINSELECT XMLQuery(‘for $j in ora:view("SCOTT", "dept")/ROWwhere $j/DEPTNO = 10return (<DEPARTMENT>{$j/DEPTNO,$j/DNAME}<EMPLOYEES> {for $i in ora:view("SCOTT", "emp")/ROWwhere $i/DEPTNO = $j/DEPTNOreturn (<EMPLOYEE>{$i/EMPNO,$i/ENAME,$i/SAL}</EMPLOYEE>)}</EMPLOYEES></DEPARTMENT>)‘RETURNING CONTENT) INTO XMLdoc FROM DUAL;IF(DBMS_XDB.CREATERESOURCE(‘/public/employees/acc_dept.xml‘, XMLdoc)) THENDBMS_OUTPUT.PUT_LINE(‘Resource is created‘);ELSEDBMS_OUTPUT.PUT_LINE(‘Cannot create resource‘);END IF;COMMIT;END;/

此時(shí),/public/employees 信息庫文件夾應包含兩個(gè)文件:acc_dept.xml(由列表 2 中的 PL/SQL 代碼生成)和 employees.xml 文件(由列表 1 中的代碼生成)。由于這些 XML 文檔存儲在同一信息庫文件夾中,因此可以使用 fn:collection 函數訪(fǎng)問(wèn)兩個(gè) XML 文檔中存儲的員工信息。然而,盡管這些 XML 文檔均包含員工 XML 元素(這些元素實(shí)際上具有相同結構),但 XML 文檔本身的結構迥然不同。在 employees.xml 中,文檔根元素為 EMPLOYEES,而 acc_dept.xml 將 DEPARTMENT 用作根元素。要解決此問(wèn)題,可以通過(guò) XQuery 使用 XPath // 構造,從而導航到 XML 文檔中的某個(gè)節點(diǎn),而不必指定該節點(diǎn)的確切路徑。以下示例演示了如何在 XQuery 表達式中使用 XPath // 構造:

SELECT XMLQuery(‘for $i in fn:collection("/public/employees")//EMPLOYEEwhere $i/SAL >= 5000order by $i/ENAMEreturn;$i‘RETURNING CONTENT) FROM DUAL;
該構造應生成以下輸出:
<EMPLOYEE><EMPNO>102</EMPNO><ENAME>De Haan</ENAME><SAL>17000</SAL></EMPLOYEE><EMPLOYEE><EMPNO>7839</EMPNO><ENAME>KING</ENAME><SAL>5000</SAL></EMPLOYEE><EMPLOYEE><EMPNO>100</EMPNO><ENAME>King</ENAME><SAL>24000</SAL></EMPLOYEE><EMPLOYEE><EMPNO>101</EMPNO><ENAME>Kochhar</ENAME><SAL>17000</SAL></EMPLOYEE>

您可以看到,以上輸出包含從 employees.xml 和 acc_dept.xml 中獲取的員工 XML 元素,這些元素表示薪酬大于或等于 5,000 美元的員工。

將 XML 分解為關(guān)系數據

如果應用程序處理關(guān)系數據而非 XML,而您需要訪(fǎng)問(wèn)的數據以 XML 格式存儲,則將 XML 分解為關(guān)系數據可能會(huì )非常有用。繼續進(jìn)行上一部分的示例,您可以使用 SQL 函數 XMLTable 將員工 XML 元素分解為虛擬表的單個(gè)列,如下所示:

SELECT emps.empno,emps.ename, emps.sal FROMXMLTable(‘for $i in fn:collection("/public/employees")//EMPLOYEEwhere $i/SAL >= 5000return;$i‘COLUMNS empno NUMBER       PATH ‘/EMPLOYEE/EMPNO‘,ename VARCHAR2(30) PATH ‘/EMPLOYEE/ENAME‘,sal   NUMBER       PATH ‘/EMPLOYEE/SAL‘) emps;
該查詢(xún)將生成以下輸出:
EMPNO ENAME                 SAL----- -------------- ----------7839 KING                 5000100 King                24000101 Kochhar             17000102 De Haan             17000

查詢(xún)外部數據源

使用 XQuery,可以基于 XML 數據以及可以用 XML 表示的非 XML 數據生成 XML 文檔,無(wú)論其位置如何:無(wú)論是存儲在數據庫中、置于網(wǎng)站上、即時(shí)創(chuàng )建還是存儲在文件系統中。但要注意,Oracle XML DB 為針對數據庫中存儲的數據進(jìn)行的 XML 操作提供了非常高的性能和可伸縮性。因此,如果您能夠完全控制所處理的數據,則最好將它移動(dòng)到數據庫中。

正如您從前面的示例中了解到的,在 Oracle XQuery 實(shí)施中,doc 和 collection XQuery 函數用于訪(fǎng)問(wèn) Oracle XML DB 信息庫中存儲的 XML 文檔??梢酝ㄟ^(guò) XMLTable 和 XMLQuery SQL 函數中的 PASSING 子句動(dòng)態(tài)綁定外部數據源??紤]以下示例。假設您的公司要為那些致力于 XQ 項目的員工支付獎金。因此,財務(wù)部發(fā)布了 empsbonus.xml 文件,其中包含有資格獲得獎金的員工列表以及該列表中輸入的每個(gè)員工的獎金數額。empsbonus.xml 文件可能如下所示:

<EMPLOYEES><EMPLOYEE><EMPNO>100</EMPNO><BONUS>1200</BONUS></EMPLOYEE><EMPLOYEE><EMPNO>101</EMPNO><BONUS>1000</BONUS></EMPLOYEE></EMPLOYEES>

在實(shí)際情況中,以上的 XML 文件可能置于網(wǎng)站上(因此可以通過(guò)互聯(lián)網(wǎng)獲得)、以文件形式存儲在本地文件系統中,或以文件資源形式存儲在 Oracle XML DB 信息庫中。就本示例而言,該文件位于網(wǎng)站上。為簡(jiǎn)單起見(jiàn),可以在目錄(Web 服務(wù)器在其中存儲可從 Web 看到的文檔)中創(chuàng )建一個(gè)員工文件夾,然后在該文件夾中插入 empsbonus.xml 文件,以便可以通過(guò)以下 URL 訪(fǎng)問(wèn) empsbonus.xml 文件:

http://localhost/employees/empsbonus.xml

接下來(lái),假設您需要基于 empsbonus.xml 文檔中存儲的數據創(chuàng )建一個(gè)報表。在該報表中,您可能不但要包含列表中顯示的獎金數額以及每個(gè)員工的員工 ID,還要包含他/她的全名。因此,可以首先使用以下查詢(xún)生成一個(gè)新的 XML 文檔(假設您以 HR/HR 的身份連接):

SELECT XMLQuery(‘for $k in 1return (<EMPLOYEES> {for $i in ora:view("employees")/ROW,$j in $emps/EMPLOYEES/EMPLOYEEwhere $i/EMPLOYEE_ID = $j/EMPNOreturn (<EMPLOYEE><EMPNO>{xs:string($i/EMPLOYEE_ID)}</EMPNO><NAME>{xs:string(fn:concat($i/FIRST_NAME, " ", $i/LAST_NAME))}</NAME><BONUS>{xs:integer($j/BONUS)}</BONUS></EMPLOYEE>)} </EMPLOYEES>)‘PASSING xmlparse (document httpuritype(‘http://localhost/employees/empsbonus.xml‘).getCLOB()) as "emps"RETURNING CONTENT).getStringVal() as RESULT FROM DUAL;

以上查詢(xún)是一個(gè)有關(guān)如何使用 XQuery 基于 XML 和非 XML 數據(以不同的方式從不同的數據源中檢索)生成 XML 文檔的示例。具體而言,使用 ora:view() 函數訪(fǎng)問(wèn) HR 演示模式中的默認 employees 關(guān)系表,并使用 PASSING 子句中的 httpuritype() 函數借助于 HTTP 訪(fǎng)問(wèn) empsbonus.xml 文檔。然后,在 FLWOR 表達式的 return 子句中構建新的 XML 文檔。最后,將獲得以下 XML 文檔:

<EMPLOYEES><EMPLOYEE><EMPNO>100</EMPNO><NAME>Steven King</NAME><BONUS>1200</BONUS></EMPLOYEE><EMPLOYEE><EMPNO>101</EMPNO><NAME>Neena Kochhar</NAME><BONUS>1000</BONUS></EMPLOYEE></EMPLOYEES>

解決性能問(wèn)題

正如您從前面的部分中了解到的,XQuery 是一種用于查詢(xún) Oracle 數據庫存儲的 XML 內容的高效方法 - 無(wú)論您是處理本地存儲的 XMLType 數據還是查詢(xún)基于關(guān)系數據構建的 XML 視圖。但根據對數據使用的存儲類(lèi)型的不同,XQuery 表達式的執行性能可能迥然不同。尤其是,Oracle XML DB 可以?xún)?yōu)化基于由 ora:view 函數創(chuàng )建的 SQL/XML 視圖而構建的 XQuery 表達式。對于 XMLType 表或列中存儲的 XML 數據,只能對使用結構化(對象-關(guān)系)存儲技術(shù)存儲的基于 XML 模式的 XMLType 數據進(jìn)行 XQuery 優(yōu)化。

所選擇的存儲模型并非是影響 XQuery 表達式執行性能的唯一因素。在某些情況下,XQuery 表達式本身的結構也可能導致性能問(wèn)題。要監控 XQuery 表達式的性能,可以打印并檢查關(guān)聯(lián)的 EXPLAIN PLAN。在 SQL*Plus 中,只需設置 AUTOTRACE 系統變量,即可打印 SQL 優(yōu)化程序使用的執行路徑。但要執行該操作,請確保創(chuàng )建 PLUSTRACE 角色,然后將其授予連接到數據庫所使用的用戶(hù)。有關(guān)如何執行此操作的信息,請參閱 Oracle 數據庫 10g 第 2 版 (10.2) 文檔《SQL*Plus 用戶(hù)指南和參考》一書(shū)中的“調整 SQL*Plus”一章。以下示例演示了如何通過(guò)檢查 EXPLAIN PLAN 生成的執行計劃來(lái)獲得好處。假設您已經(jīng)將 PLUSTRACE 角色授予默認用戶(hù) OE,以 OE/OE 的身份登錄并運行以下查詢(xún):

SET AUTOTRACE ON EXPLAINSELECT count(*)FROM oe.purchaseorder, XMLTable(‘for $i in /PurchaseOrder/Userwhere $i = "CJOHNSON"return $i‘PASSING OBJECT_VALUE) ptab;
這將生成以下輸出:
COUNT(*)----------9Execution 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(‘<privilege...

您可能對為以上查詢(xún)生成的執行計劃并不滿(mǎn)意。尤其是,所處理的行數可能非常大。由于 SQL 調整的主要目標是避免訪(fǎng)問(wèn)對結果沒(méi)有任何影響的行,因此可能要繼續調整查詢(xún)以?xún)?yōu)化性能。對查詢(xún)中包含的 XPath 表達式進(jìn)行重新建模后,可以再次重試它,如下所示:

SELECT count(*)FROM oe.purchaseorder, XMLTable(‘for $i in /PurchaseOrderwhere $i/User = "CJOHNSON"return $i/User‘PASSING OBJECT_VALUE) ptab;
這次,輸出應如下所示:
COUNT(*)----------9Execution 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‘ ANDSYS_CHECKACL("ACLOID","OWNERID",xmltype(‘<privilege...

您可以看到,以上顯示的查詢(xún)生成相同的最終結果,但它們的執行計劃并不相同。查看最后一個(gè)示例中的 XQuery 表達式,您可能會(huì )注意到它迭代頂層 PurchaseOrder 元素,其中的每個(gè) PurchaseOrder 元素都表示基于 PurchaseOrder XMLType 模式的表中的一行。這意味著(zhù)實(shí)際上重寫(xiě) XQuery 表達式,以迭帶基礎對象表(用于存儲分解的 PurchaseOrder 文檔)中的行。與查詢(xún)要迭代不表示基礎表中的單個(gè)行的 XML 元素相比,該方法的性能更好一些。

但在某些情況下,很難發(fā)現 XQuery 表達式的哪個(gè)構造將使某些查詢(xún)的性能更好。這就是為什么最好在開(kāi)發(fā)階段使用調整工具的原因。

將動(dòng)態(tài)變量綁定到 XQuery 表達式

另一種可以顯著(zhù)提高 XQuery 表達式執行性能的技術(shù)是使用綁定動(dòng)態(tài)變量。使用綁定變量(而不是將變量串聯(lián)為字符串)可以使 Oracle 重用 SQL 語(yǔ)句,從而減少分析開(kāi)銷(xiāo)并顯著(zhù)提高應用程序的性能??梢栽?XMLQuery 和 XMLTable SQL 函數中使用 PASSING 子句將動(dòng)態(tài)變量綁定到 XQuery 表達式。該技術(shù)使您可以根據客戶(hù)端代碼中計算的參數動(dòng)態(tài)生成 XML。列表 3 中的示例演示了如何在從 PHP 腳本執行的 XQuery 查詢(xún)中使用綁定變量。

列表 3:使用綁定變量

<?php//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")/ROWwhere $i/EMPLOYEE_ID = $empnoreturn (<EMPLOYEE>{$i/EMPLOYEE_ID,$i/EMAIL,$i/JOB_ID}</EMPLOYEE>)‘."‘".‘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 中顯示的腳本應生成以下輸出(注意,瀏覽器中可能不會(huì )顯示標記):
<EMPLOYEE><EMPLOYEE_ID>100</EMPLOYEE_ID><EMAIL>SKING</EMAIL><JOB_ID>AD_PRES</JOB_ID></EMPLOYEE>

XQuery 與 XSLT

盡管 Oracle 在 Oracle XML DB 中提供了一個(gè)自帶 XSLT 處理器,但在很多情況下(尤其是在處理大型文檔時(shí)),XQuery 對于構建 XML 更高效。此外,XQuery 表達式通常比為同一作業(yè)設計的 XSLT 樣式表更具可讀性,并且更清楚。與 XSLT 一樣,XQuery 不但可用于將一個(gè) XML 文檔轉換為另一個(gè) XML 文檔,而且還可用于將 XML 轉換為另一種基于文本的格式,如 HTML 或 WML。

在本文前面的查詢(xún) XMLType 數據部分中,您看到了一個(gè)有關(guān)使用 XQuery 將一個(gè) XML 文檔轉換為另一個(gè) XML 文檔的示例。具體而言,該示例使用 XQuery 表達式計算示例數據庫模式 OE 的 purchaseorder 表中存儲的訂單的訂單總計,然后為處理的每個(gè)訂單生成了一個(gè) OrderTotal XML 元素。實(shí)際上,您可以使用 XSLT 執行相同操作。為此,您首先需要創(chuàng )建一個(gè)應用于 PurchaseOrder XML 文檔的 XSLT 樣式表,以生成相應的 OrderTotal 元素。對于此示例,可以使用列表 4 中所示的 XSLT 樣式表。

列表 4:使用 XSLT 計算小計總和 (Quantity * UnitPrice)
<?xml version=‘1.0‘ encoding=‘utf-8‘ ?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="xml"<xsl:template match="/"><xsl:for-each select="PurchaseOrder"><xsl:variable name="reference" select="Reference"<xsl:variable name="Parts" select="LineItems/LineItem/Part"<xsl:variable name="orderTotal"><xsl:call-template name="orderAmount"><xsl:with-param name="Parts" select="$Parts"<xsl:with-param name="sum"    select="0"</xsl:call-template></xsl:variable><OrderTotal><Reference><xsl:value-of select="$reference"/></Reference><Total><xsl:value-of select="format-number($orderTotal, ‘######0.00‘)"/></Total></OrderTotal></xsl:for-each></xsl:template><xsl:template name="orderAmount"><xsl:param name="Parts"/><xsl:param name="sum"/><xsl:choose><xsl:when test="not($Parts)"><xsl:copy-of select="$sum"/></xsl:when><xsl:otherwise><xsl:variable name="collector" select="$sum + $Parts[1]/@Quantity * $Parts[1]/@UnitPrice"/><xsl:call-template name="orderAmount"><xsl:with-param name="Parts" select="$Parts[position()>=2]"/><xsl:with-param name="sum" select="$collector"/></xsl:call-template></xsl:otherwise></xsl:choose></xsl:template></xsl:stylesheet>

為方便起見(jiàn),您可能需要將此 XSL 樣式表保存在數據庫中,然后再開(kāi)始使用它。例如,您可以將樣式表作為文件資源保存在 Oracle XML DB 信息庫中。執行該操作的方法之一是將樣式表作為文件保存到本地文件系統中,然后使用以下某個(gè)互聯(lián)網(wǎng)協(xié)議將它移動(dòng)到 XML 信息庫:FTP、HTTP 或 WebDAV。假設您已經(jīng)將列表 4 中的 XSLT 樣式表作為 orderTotal.xsl 保存在 /public 信息庫文件夾中,現在可以按以下示例所示將它用作 XMLTransform SQL 函數的參數(假設您以 OE/OE 的身份登錄):

SELECT XMLTRANSFORM(OBJECT_VALUE,xdbUriType(‘/public/orderTotal.xsl‘).getXML()).GetStringVal() AS RESULT FROMpurchaseorder WHERE existsNode(OBJECT_VALUE, ‘/PurchaseOrder[User = "EABEL"]‘) = 1;

以上查詢(xún)將處理用戶(hù) EABEL 請求的所有訂單(即存儲在 XMLType 的默認 PurchaseOrder 表中的訂單)并將生成與查詢(xún) XMLType 數據部分中的 XQuery 查詢(xún)相同的輸出。

將列表 4 中的 orderTotal XSLT 樣式表與查詢(xún) XMLType 數據部分中的示例使用的 XQuery 表達式進(jìn)行比較,您可能會(huì )注意到,XQuery 方法要比 XSLT 方法更具吸引力。至少在使用 XQuery 時(shí),您只需編寫(xiě)很少的代碼即可獲得相同的最終結果。

查詢(xún) RSS 新聞提供

由于 RSS 新聞提供本質(zhì)上是一個(gè)托管的 XML 文件(RSS 新聞閱讀器從中獲取頭條新聞或其他內容),因此可以像處理任何其他可以通過(guò) Web 獲得的 XML 文檔那樣來(lái)處理它。正如您在本文前面的查詢(xún)外部數據源部分中所見(jiàn),可以使用 XQuery 查詢(xún)任何可以通過(guò) URL 訪(fǎng)問(wèn)的 XML。您通過(guò) XMLTable 和 XMLQuery SQL 函數中的 PASSING 子句動(dòng)態(tài)綁定所有外部 XML 數據源。以下是一個(gè)查詢(xún) RSS 新聞提供的 XQuery 示例:

SELECT XMLQuery(‘for  $i in $h//channelreturn;<headlines><title>Recent OTN Headlines related to PHP technology</title>{$i/lastBuildDate}<item>{for $j in $h//itemwhere  ora:contains($j, "PHP")return <item> {($j/title, $j/link)}</item>}</Item></headlines>‘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 應生成一個(gè) XML 文檔,其中包含 Oracle 技術(shù)網(wǎng) (OTN) 最近發(fā)布的與 PHP 技術(shù)相關(guān)的頭條新聞列表。所生成的 XML 文檔可能如下所示:

<headlines><title>Recent OTN Headlines related to PHP technology</title><lastBuildDate>Tue, 01 Nov 2005 19:37:42 GMT</lastBuildDate><items><item><title>Oracle Database 10g Express Edition:Free to Develop, Deploy, and Distribute</title><link>http://www.oracle.com/technology/xe</link></item><item><title>Explore the Oracle+PHP Cookbook</title><link>http://www.oracle.com/technology/pub/articles/oracle_php_cookbook</link></item><item><title>Download Zend Core for Oracle</title><link>http://www.oracle.com/technology/tech/php/zendcore/index.html</link></item></items></headlines>

但在開(kāi)發(fā)實(shí)際應用程序時(shí),您將很可能需要 XQuery 表達式直接生成 HTML 標記,而不是僅僅生成一個(gè)如上所示的 XML 文檔。這樣,您便可以構建一個(gè)更靈活、可維護性更高的應用程序,原因是在這種情況下,所有 RSS 處理(從提取必要的數據到將它包裝在 HTML 標記中)都將轉移到數據庫。這使您不必編寫(xiě)負責 RSS 處理的應用程序代碼。實(shí)際上這意味著(zhù)您不必在諸如 RSS 新聞提供的結構已經(jīng)更改的情況下修改應用程序代碼。相反,您只需修改用于 RSS 處理的 XQuery 表達式。

總結

您已經(jīng)在本文了解到,XQuery 是一個(gè)綜合的查詢(xún)語(yǔ)言,它提供了一種用于查詢(xún)、構建和轉換 XML 數據的高效方法。盡管 Oracle XQuery 實(shí)施使您可以操作任何可以用 XML 表示的數據(無(wú)論它存儲在數據庫中、位于網(wǎng)站上還是存儲在文件系統中),但將處理的數據移動(dòng)到數據庫中始終是一個(gè)不錯的主意。對于數據庫中存儲的數據,Oracle XML DB(對 XPath 重寫(xiě)使用同一機制)只能顯著(zhù)優(yōu)化處理那些基于以下數據構建的 XQuery 表達式:這些數據包括關(guān)系數據、對象-關(guān)系數據或使用結構化(對象-關(guān)系)存儲技術(shù)存儲的基于 XML 模式的 XMLType 數據。


Yuli Vasiliev (jvyul@yahoo.com) 是一位軟件開(kāi)發(fā)人員、自由作者和顧問(wèn)。他目前感興趣的領(lǐng)域包括開(kāi)放源開(kāi)發(fā)、Oracle XML 技術(shù)和面向服務(wù)的體系結構。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
用于數據的 XML: XPath 2.0 有哪些新特性?
Oracle XMLTable 使用教程與實(shí)例
XSLT輕松入門(mén)第四章:XPath的語(yǔ)法
高級SQL優(yōu)化(二)
XSL基本概念
XML數據庫:最新進(jìn)展和發(fā)展方向
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久