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

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

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

開(kāi)通VIP
走進(jìn) SQL/XML

走進(jìn) SQL/XML


作者:Tim Quinlan

 

概覽 SQL 與 XML 的互操作性,了解如何著(zhù)手處理存儲在數據庫中的 XML 文檔。

2006 年 12 月發(fā)布

XML 數據通常用于現在的生產(chǎn)系統,是數據庫實(shí)現的主要部分。過(guò)去,這一事實(shí)給數據庫開(kāi)發(fā)人員帶來(lái)了設計問(wèn)題,使得他們必須存儲、查詢(xún)和更新諸如非結構化 LOB 的 XML 數據,或者將數據“分解”到關(guān)系表中,然后再將其重新組合。該方法導致編程的復雜且低效,因為這些訪(fǎng)問(wèn)機制是不成熟的。

首次隨 Oracle9i 數據庫第 2 版推出的 Oracle XML DB 特性提供了用于在數據庫中存儲、檢索和操作 XML 數據的新功能。然而,Oracle 10g 第 2 版 XML DB 極大地擴展了該初始方法,其中 XML 數據就像數據庫中的 BLOB 一樣。

本文適用于不了解 Oracle 中 XML 實(shí)現的 DBA 或開(kāi)發(fā)人員:其中簡(jiǎn)要概述了 SQL 和 XML 互操作性和如何著(zhù)手處理存儲在 Oracle 10g 第 2 版數據庫中的 XML 文檔,此外,還介紹了 DBA 和開(kāi)發(fā)人員在數據庫中使用 XML 之前應該熟悉的由 Oracle 數據庫 10g 第 2 版提供的大量新特性。使用這些 SQL/XML 特性,可以輕松增強您在使用關(guān)系數據時(shí)獲取的技能,以便幫助您使用 XML。

什么是 Oracle 的 XML 實(shí)現?

Oracle 已經(jīng)通過(guò)數據庫的 XML DB 組件實(shí)現了 XML,該組件是企業(yè)版和標準版的標準特性。通過(guò)數據庫配置助手 (DBCA) 或者運行一個(gè)目錄腳本 catqm.sql,可以輕松安裝 Oracle XML DB。XML DB 產(chǎn)品提供本文討論的所有特性。

要驗證是否安裝了 XML DB,只需運行下面的 SQL:

select comp_name from dba_registry where comp_name like ‘%XML%‘;COMP_NAMEOracle XML Database

也可以查看 XML DB 模式及其對象來(lái)確認是否安裝了 Oracle XML DB。

SQL 和 XML 協(xié)作

SQL/XML 標準已處在開(kāi)發(fā)之中,以便提供一個(gè)允許我們從關(guān)系查詢(xún)生成 XML 的機制,并反之使我們能夠從 XML 文檔提交 SQL 數據。Oracle 數據庫 10g 第 2 版中的 Oracle XML DB 實(shí)現 SQL 2003 和來(lái)自即將推出的 SQL/XML 標準版的特性。Oracle 中這些標準的實(shí)現使我們能夠以在之前 SQL 標準中不可能的方式查看 XML 文檔。

新數據類(lèi)型。Oracle9i 數據庫第 1 版中引入了一個(gè)新數據類(lèi)型 XMLType,它允許在 SQL 中訪(fǎng)問(wèn)數據庫中的 XML 文檔,同時(shí)允許 XML 開(kāi)發(fā)人員在文檔中使用 XML 標準。該數據類(lèi)型通知數據庫該內容是 XML 格式的,并允許我們在 XML 文檔上執行查詢(xún)。使用 XMLType(而非一個(gè)關(guān)系或 CLOB 實(shí)現)在應用程序和存儲模型間提供一個(gè)分離層。該分離允許數據移到一個(gè)不同的存儲模型,而不局限于 CLOB 或關(guān)系模型。XMLType 可用于創(chuàng )建表、列或視圖。它還可用作參數和變量的數據類(lèi)型。

內置的 XML 方法可以處理文檔內容,允許我們創(chuàng )建、提取和索引 XML 數據。索引可以使用 b 樹(shù)、文本索引和基于函數的索引執行。實(shí)際上,與 XPath 合并的 XMLType 數據可用于查看文檔。該功能通過(guò) PL/SQL 和 Java API 提供。XMLType 可用在 PL/SQL、使用 JDBC 的 Java 以及 Oracle Data Provider for .Net 中。這個(gè)功能強大且相對較新的數據類(lèi)型將在本文中廣泛使用。

存儲結構。Oracle 的 XML 實(shí)現為我們提供了以?xún)煞N不同方式存儲數據的靈活性:結構化存儲和非結構化存儲。XMLType 數據在存儲為單個(gè) LOB 列時(shí)是非結構化的,在實(shí)現為對象集時(shí)是結構化的。

它的一個(gè)特定示例是 XMLType 表,該表可以使用這兩種存儲模型之一實(shí)現。XMLType 表在使用如下所示的“XMLType store as CLOB”語(yǔ)法實(shí)現為 LOB 時(shí)是非結構化的:
create table table_name of XMLtypeXMLType store as CLOB;

讓我們重點(diǎn)看一下 XML 數據的結構化存儲和非結構化存儲并進(jìn)行更詳細的了解。

結構化存儲。將結構化 XML 存儲實(shí)現為一組對象。這些對象可通過(guò)具有可以在表間實(shí)現的引用約束的表以關(guān)系格式實(shí)現。它們也可以使用一個(gè) XMLSchema 實(shí)現,以便將一個(gè) XMLType 文檔分解為一組對象。

在使用關(guān)系表的情況中,可以因此對這些表進(jìn)行預先設計,或者使用現有表。該文檔實(shí)際上通過(guò)關(guān)系表存儲為“虛擬”文檔,并保留其邏輯結構。該方法可維護文檔對象模型 (DOM) 保真度,但是它不是文檔的逐字節物理表示。這可以通過(guò)創(chuàng )建一個(gè)關(guān)于現有關(guān)系數據的 XMLType 視圖來(lái)完成。

結構化存儲比非結構化存儲具有一些性能優(yōu)勢,選擇它可通過(guò)表和索引設計提供更多的查詢(xún)和更新優(yōu)化。結構化存儲上的 XML 操作有助于減少內存和存儲,因為沒(méi)有存儲 XML 標記,而且存在更細粒度的數據檢索和使用?;?b 樹(shù)和基于函數的索引使用得到了增強,而且使用 XPath 重寫(xiě)可在文檔的部分上執行適當更新。所有這些都對性能有所幫助,本文稍后將詳細討論。

使用結構化存儲也有一些缺點(diǎn)。插入和檢索整個(gè)文檔需要更多開(kāi)銷(xiāo)。此外,靈活性有限,因為只能存儲匹配 XMLSchema 的文檔 — 但是在某些情況中,這實(shí)際上是個(gè)優(yōu)勢。文檔不存儲為逐字節原始表示,而且不保留文檔中的數據順序。但是,這將不會(huì )出現數據丟失的情況。

我們通常會(huì )將高度結構化的數據看作是 XML,其中數據的每個(gè)元素都可以清晰定義。

非結構化存儲。XML 可以使用 CLOB 存儲以非結構化方式存儲在 Oracle 中,以便 SQL 查詢(xún)不會(huì )知道該數據的結構。該數據可以使用 Oracle 的 XMLType 數據類(lèi)型存儲。

如果想讓存儲數據匹配文檔的準確物理表示,可以選擇非結構化數據。此外,如果該數據不經(jīng)常更新,或者整個(gè)文檔(而非部分文檔)有大量的插入和讀取,則將數據整體放在一處可能更高效。在某些情況中,您需要保持文檔的靈活性,而且在這些情況中,XMLType 表或列可能是有用的。

非結構化存儲的缺點(diǎn)是,對部分文檔的更新通常不如結構化數據那樣高效。此外,使用函數從 CLOB 構造 DOM 的 XPath 操作將使用大量的系統資源。非結構化數據的其他問(wèn)題是,SQL 約束無(wú)法實(shí)現,而且內存管理也不是如此有效。

我們通常不將非結構化數據作為 XML 數據考慮,并將其中大部分或所有數據只看作是單個(gè) CLOB。

了解了這些存儲模型后,現在讓我們來(lái)看一些命名特性。

命名空間中有什么?

這是一個(gè)大主題,也是需要了解的較復雜的 XML DB 概念之一。在本文中,我們將介紹一些命名空間概念,以便您了解其要旨所在及其用法。

命名空間用于描述 XML 文檔中的一組相關(guān)屬性或元素。命名空間可用于確保文檔構造有完全唯一的名稱(chēng)。XMLSchema 尤其要利用該特性,因為目標命名空間通常與 XMLSchema 的 URI 相同。命名空間示例如下所示。請注意,該命名看起來(lái)類(lèi)似于一個(gè) Internet URL。該命名標準由萬(wàn)維網(wǎng)聯(lián)盟 (W3C) 建議,但并非必需。該 URI 用于唯一標識數據庫中注冊的 XMLSchema 的名稱(chēng),而且無(wú)需是文檔所處位置的物理 URL。

XMLType 方法和 XML 函數使用命名空間前綴。當 XML 文檔沒(méi)有目標命名空間時(shí),該命名空間前綴將位于 noNameSpace 命名空間中。屬性 xsi:noNamespaceSchemaLocation 可用于模式 URI。

如果元素不具備另一個(gè)命名空間前綴,默認情況下,在將某個(gè)命名空間應用到描述它的元素時(shí),可使用該命名空間。

通常您將看到兩個(gè)特定的命名空間。它們是 http://www.w3.org/2001/XMLSchema(完整的 XMLSchema 命名空間)和 http://xmlns.oracle.com/xdb(Oracle 提供的 XML DB 命名空間)。第二個(gè)命名空間具有寫(xiě)入基礎 SQL 函數的函數。一些 XPath 函數也進(jìn)行重寫(xiě)。例如 ora:contains、ceiling、floor、not、string-length、substring 和 translate。XML DB 使用的屬性也屬于該命名空間。

定義元素時(shí),我們可以指定該元素的命名空間。在 XML 中,我們可以將它定義為

<elementName xmlns:ab="http.name.com" /> 

如您所見(jiàn),我們提供了一個(gè) elementName,它是我們將使用的元素(例如,“orders”)。Xmlns 是保留字,它告訴我們這是一個(gè)命名空間定義。“ab”部分稱(chēng)為前綴。該前綴是一個(gè)綁定到 URL 的簡(jiǎn)稱(chēng)。在本例中,ab 綁定到‘http.name.com’,而且 ab 可以加為元素名的前綴。

下面我們將創(chuàng )建一個(gè)非常小的模式,并聲明綁定前綴 xs 到 http://www.w3.org/2001/XMLSchema 以及聲明前綴 xdb 到 http://xmlns.oracle.com/xdb。為了聲明該命名空間,我們使用 xmlns 綁定它們。請注意,xs 前綴在本例中用在模式元素名稱(chēng)上。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:xdb= "http://xmlns.oracle.com/xdb" version="1.0"><xs:element name="INVOICESCHEMA" xdb:defaultTable="INVOICESCHEMA"><xs:complexType><xs:sequence><xs:element name="MailAddressTo"><xs:complexType><xs:sequence><xs:element name="Person" type="xs:string"<xs:element name="Street" type="xs:string"/></xs:sequence><xs:attribute name="id" type="xs:string" use="required"/></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element></xs:schema>

這里我們只是粗略介紹了一下命名空間。有關(guān)該主題的更多信息,請參閱 Oracle 技術(shù)網(wǎng) (OTN) 上的 Oracle XML DB 開(kāi)發(fā)人員指南 10g 第 2 版。

使用 XML

將數據添加到 XMLType 表和列中。正如您可能預期到的,有很多選項可供我們將 XML 數據添加到數據庫中??梢允褂?SQL、PL/SQL、Java 和 C 程序插入數據。也可以使用 XMLType 表的 SQL*Loader 和 Import/Export 函數將數據加載到數據庫中??梢允褂?Oracle Streams 來(lái)移動(dòng) XML 數據,還可以使用 DBMS_XDB 函數?,F在,就讓我們來(lái)探究一個(gè)簡(jiǎn)單易用的方式來(lái)加載 XML 數據。

在本例中,我們將使用 SQL 插入將一個(gè) XML 文檔從文件加載到表中,以便從 bfile 加載該 XML 文檔。該文件需要通過(guò)一個(gè)數據庫目錄訪(fǎng)問(wèn)。為此,我們將創(chuàng )建一個(gè)目錄以指向存儲該 XML 文檔文件的文件。請注意,要執行本文中的示例,您必須確保所用用戶(hù)具有 xdbadmin 角色。

create or replace directory xmldir as ‘/u01/app/oracle/admin/db01/sql‘;

現在我們可以用兩種方式創(chuàng )建包含 XMLType 數據的表。第一個(gè)將是具有 XMLType 列的表。第二個(gè)將是定義為類(lèi)型 XMLType 的表。

1. 創(chuàng )建一個(gè)包含 XML 列的表。

create table invoiceXML_col (inv_id number primary key,inv_doc XMLType);

2. 創(chuàng )建一個(gè) XML 表。

create table invoiceXML_tbl of XMLtype; 

以上每一個(gè)語(yǔ)句都在每個(gè)表中隱式創(chuàng )建兩個(gè)索引 — 一個(gè)用于主鍵,另一個(gè)用于 LOB。

現在我們要將一個(gè)發(fā)票文檔插入到這兩個(gè)表中。請注意,我們要使用字符集 AL32UTF8,并指定它傳送字符集編碼來(lái)供要讀取的文件使用。數據將插入這兩個(gè)表以顯示這兩個(gè) SQL 語(yǔ)句間的相似性。

Insert into invoicexml_col values (1,XMLType(bfilename(‘XMLDIR‘, ‘invoicexml.txt‘),nls_charset_id(‘AL32UTF8‘) ));Insert into invoicexml_tbl values(XMLType(bfilename(‘XMLDIR‘, ‘invoicexml.txt‘),nls_charset_id(‘AL32UTF8‘)));

我們現在已經(jīng)使用 XMLType 表和列將兩個(gè) XML 文檔加載到了數據庫中。就是這么簡(jiǎn)單。

注冊和實(shí)現模式類(lèi)型化數據

如果處理命名空間和存儲技術(shù)不足,XMLType 數據也可以實(shí)現為模式類(lèi)型化或非類(lèi)型化數據。XMLSchema 可將文檔與提供文檔結構和內容信息的 XMLSchema 相關(guān)聯(lián)。這為文檔提供了更好的記錄、驗證和控制。該模式中的信息可用于提交更有效的查詢(xún)和更新處理。XMLSchema 也允許將 XML 文檔存儲為結構化存儲數據,因為該文檔可以通過(guò) XMLSchema 分解為一組對象。用于存儲該文檔的對象模型由模式定義確定。XMLType 方法 schemaValidate() 和 isSchemaValid() 允許使用模式定義編輯 XMLType 文檔。

我們如何創(chuàng )建模式并在 XML 文檔中使用它?為此,我們需要創(chuàng )建一個(gè) XMLSchema 定義

  1. 注冊該模式
  2. 創(chuàng )建一個(gè)基于 XMLSchema 的表
  3. 將數據插入其中

下面的示例分四步進(jìn)行了說(shuō)明。

1. 首先,在目錄 XML_DIR 下的文件 invoiceformtest.xsd 中創(chuàng )建一個(gè)模式定義。該清單如下所示:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:xdb=http://xmlns.oracle.com/xdb version="1.0"><xs:element name="INVOICEFORMTEST" xdb:defaultTable="INVOICEFORMTEST"><xs:complexType><xs:sequence><xs:element name="MailAddressTo"><xs:complexType><xs:sequence><xs:element name="Person" type="xs:string"/><xs:element name="Street" type="xs:string"/><xs:element name="City" type="xs:string"/><xs:element name="State" type="xs:string"/><xs:element name="Zipcode" type="xs:string"/></xs:sequence><xs:attribute name="id" type="xs:string" use="required"/></xs:element></xs:sequence></xs:complexType></xs:element></xs:schema>

2. 使用過(guò)程 DBMS_XMLSCHEMA.registerSchema 在數據庫中注冊上面的模式。您用來(lái)連接到數據庫的用戶(hù)名需要修改會(huì )話(huà)權限,以便該模式可以成功注冊。

BEGINDBMS_XMLSCHEMA.registerSchema(SCHEMAURL => ‘http://xmlns.oracle.com/xdb/invoiceformtest.xsd‘,SCHEMADOC => bfilename(‘XMLDIR‘,‘invoiceformtest.xsd‘),CSID => nls_charset_id(‘AL32UTF8‘));END;/

要刪除該模式,只需運行 DBMS_XMLSCHEMA.deleteSchema 語(yǔ)句,如下所示:

BEGINDBMS_XMLSCHEMA.deleteSchema(SCHEMAURL => ‘http://xmlns.oracle.com/xdb/invoiceformtest.xsd‘,DELETE_OPTION => dbms_xmlschema.DELETE_CASCADE_FORCE);END;/

3. 由于上面模式定義中的 xdb:defaultTable="INVOICEFORMTEST" 語(yǔ)句,以上語(yǔ)句還創(chuàng )建了表 invoiceformtest。沒(méi)有它,將創(chuàng )建一個(gè)生成的名稱(chēng)(您不想使用該名稱(chēng))。

4. 現在,我們準備將文檔輸入到 XML 文檔內基于 XMLSchema 的表中,該文檔存儲在 XML_DIR 中并使用實(shí)現的模式指定的格式。

Insert into invoiceformtest values(XMLType(bfilename(‘XMLDIR‘, ‘invoiceformtest.txt‘),nls_charset_id(‘ AL32UTF8‘)));

來(lái)看一下我們剛剛使用 XML 文檔上的 object_value pseudocolumn 創(chuàng )建的內容。

SQL> select object_value from invoiceformtest;OBJECT_VALUE<INVOICEFORMTEST><MailAddressTo id="1"><Person>Joe Smith</Person><Street>10 Apple Tree Lane</Street><City>New York</City><State>NY</State><Zipcode>12345</Zipcode></MailAddressTo></INVOICEFORMTEST>

完成!

了解 XQuery 函數和表達式

XQuery 是 W3C 針對查詢(xún)語(yǔ)言開(kāi)發(fā)的一個(gè)標準,用于從 XML 文件提取信息。它允許我們訪(fǎng)問(wèn)物理 XML 文檔或者通過(guò) XML 視圖虛擬化為 XML 文檔的關(guān)系數據。使用的表達式可以是簡(jiǎn)單的查詢(xún)或較大查詢(xún)的一部分,而且可以包括標準函數,例如,日期/時(shí)間、算術(shù)或字符串函數以及用戶(hù)定義的函數。XQuery 是 Oracle 數據庫 10g 第 2 版中的新特性,并受 XMLQuery() 和 XMLTable() 函數支持。使用這兩個(gè)函數的示例稍后在“XMLQuery() 和 XMLTable()”部分中有述。

XQuery 使用 XPath 表達式(如下所述)定位 XML 文檔中的詳細項??蓪⑵淇醋魇?Oracle 數據庫 10g 第 2 版中引入的 XMLQuery() 和 XMLTable() 函數的基礎,本文稍后有述。

以下將介紹一些更重要的 XQuery 表達式(包括 XPath、XMLSequence 和 FLWOR)。

XPath、XMLSequence 和 FLWOR 表達式

XPath。XPath 提供使用定址技術(shù)在 XML 文檔中定位項的方式,而且它通過(guò)一個(gè)文檔結構使用邏輯路徑處理這些項。它允許程序員在較高的抽象級別處理文檔,方法是通過(guò)文檔指定路由而非指向特定元素。XPath 使用節點(diǎn)概念定義路徑在何處開(kāi)始,然后定義一個(gè)“邏輯樹(shù)”,該樹(shù)包括諸如 attribute、self、parent、child 和 ancestor 等關(guān)系。換言之,XPath 會(huì )將 XML 文檔建模為節點(diǎn)樹(shù)。節點(diǎn)類(lèi)型分為若干種,例如,元素節點(diǎn)、屬性節點(diǎn)和文本節點(diǎn)。XPath 可以確定一個(gè)方式來(lái)為每個(gè)節點(diǎn)計算字符串值。

憑借 XPath 表達式,您可使用基于標準的方式查詢(xún)和更新 XML 文檔。我們將使用 extract、extractValue、existsNode 和 XMLSequence 函數來(lái)演示 XPath 功能,期間將用到我們已創(chuàng )建的 invoicexml_tbl 文檔以及插入到其中的數據。

查詢(xún)要在 XPath 示例中使用的文檔。讓我們看一下如何使用 XPath 函數通過(guò) SQL 搜索 XML (XMLType) 數據。為此,來(lái)看一下要使用 object_value pseudocolumn 從 XMLType 表檢索 XML 文檔時(shí)涉及的文檔。

SQL> select object_value from invoicexml_tbl;OBJECT_VALUE<Invoice><MailAddressTo id="PA"><Person>Joe Smith</Person><Street>10 Apple Tree Lane</Street><City>New York</City><State>NY</State><Zipcode>12345</Zipcode></MailAddressTo><MailAddressFrom id="PA"><Person>Ed Jones</Person><Street>11 Cherry Lane</Street><City>Newark</City><State>NJ</State><Zipcode>67890</Zipcode></MailAddressFrom><Details id="2006Sept1to30PA"><FromTo>Sept 1, 2006 to Sept 30, 2006</FromTo><Hours>70</Hours><Rate>30</Rate><Taxes>210</Taxes><TotalDue>2310</TotalDue><InvDate>Oct 1, 2006</InvDate><Contractor>Ed Jones</Contractor></Details></Invoice>

使用 extract。使用 extract 時(shí),通過(guò)將 extract 與 object_value 合并,可從文檔選擇單個(gè)節點(diǎn)及其葉節點(diǎn)。換言之,我們可以查看存儲為 XMLType 的 XML 文檔。無(wú)論我們使用的是結構化數據還是非結構化數據以及數據是否基于模式,情況都是如此。開(kāi)始提取 MailAddressTo 節點(diǎn)及其葉節點(diǎn)。

select extract(object_value, ‘/Invoice/MailAddressTo‘) from invoicexml_tbl;EXTRACT(OBJECT_VALUE,‘/INVOICE/MAILADDRESSTO‘)<MailAddressTo id="PA"><Person>Joe Smith</Person><Street>10Apple Tree Lane</Street><City>New York</City><State>NY</State><Zipcode>12345</Zipcode></MailAddressTo>

如您所見(jiàn),該輸出包括文檔的 MailAddressTo 部分,不適合打?。ǜ袷交?。此外,用于實(shí)現它的語(yǔ)法非常簡(jiǎn)單。重要的是,我們能夠在無(wú)需轉儲整個(gè)內容的情況下查看文檔。

使用 extractValue。葉節點(diǎn)中存在的數據值可以使用 extractValue 提取。較高級的節點(diǎn)(例如 MailAddressTo)無(wú)法使用該函數提取。請注意,它的輸出不是 XML 語(yǔ)法格式,其中只包含該數據值。

select extractValue(object_value, ‘/Invoice/MailAddressTo/Person‘)Person from invoicexml_tbl;PERSONJoe Smith

使用 existsNode。ExistsNode 以類(lèi)似的方式使用,以便在節點(diǎn)級(只能在節點(diǎn)級)搜索文檔的特定值。它返回一個(gè) True 或 False 標志來(lái)指定搜索是否成功。= 1 謂詞不是次數,表示的是 True 條件,而 = 0 表示 False。

Select count(*) from invoicexml_tblwhere existsNode(object_value, ‘/Invoice/MailAddressTo[Person="Joe Smith"]‘) = 1;COUNT(*)1

使用 XMLSequence。與 extractValue(只可從單個(gè)節點(diǎn)提取的值)不同,XMLSequence 可用于查看文檔的多個(gè)節點(diǎn)或某個(gè)片段。它通過(guò)創(chuàng )建包含 XMLType 對象的虛擬表來(lái)完成此操作。讓我們使用 MailAddressTo 分支節點(diǎn)來(lái)對 extractValue 和 XMLSequence 進(jìn)行比較。

select extractValue(object_value, ‘/Invoice/MailAddressTo‘) from invoicexml_tbl;from invoicexml_tbl*ERROR at line 2:ORA-19025: EXTRACTVALUE returns value of only one node

該 ORA-19025 消息具有自我說(shuō)明性。幸運的是,我們可以通過(guò)重構該查詢(xún)并使用 XMLSequence 解決該問(wèn)題,如下所示:

select value(addr)from invoicexml_tbl i,table(XMLSequence(extract(i.object_value, ‘/Invoice/MailAddressTo‘))) addrwhere existsNode(i.object_value, ‘/Invoice/Details[@id="2006Sept1to30PA"]‘) = 1;VALUE(ADDR)<MailAddressTo id="PA"><Person>Joe Smith</Person><Street>10Apple Tree Lane</Street><City>New York</City><State>NY</State><Zipcode>12345</Zipcode></MailAddressTo>

由于 XMLSequence 創(chuàng )建一個(gè)虛擬表,我們也可以在葉節點(diǎn)上使用該函數。

select value(person)from invoicexml_tbl i,table(XMLSequence(extract(i.object_value, ‘/Invoice/MailAddressTo/Person‘))) personwhere existsnode(i.object_value, ‘/Invoice/Details[@id="2006Sept1to30PA"]‘) = 1;VALUE(PERSON)<Person>Joe Smith</Person>

FLWOR。FOR、LET、WHERE、ORDER BY 和 RETURN(FLWOR;發(fā)音為“flower”)是 XQuery 語(yǔ)法中最重要且最強大的表達式之一。FOR 或 LET 必須存在,WHERE 和 ORDER BY 是可選的,而 RETURN 是必需的。FLWOR 本身就是一個(gè)有待介紹的大主題。本節將為您簡(jiǎn)要介紹一下該語(yǔ)句的強大功能。

FOR 通過(guò)迭代方式以變量的列出順序綁定一個(gè)或多個(gè)變量。前面列出的值之后可用在一組后續的值中。這種工作方式也類(lèi)似于 SQL From 子句。前面列出的值之后可用在一組后續的值中,如下所示:

For $var in (1,2,3) , $varPlus5 in (5+$var, 5+$var, 5+$var)

這三個(gè)迭代將 $var 和 $varPlus5 分別設置為 1,6;2,7 和 3,8。

LET(類(lèi)似于 FOR)以迭代方式綁定變量,可以使用以前計算的值來(lái)計算值。與使用 FOR 一樣,可將 LET 看作 SQL FROM 字句。LET 也可以用于執行連接。

WHERE 過(guò)濾數據的方式與 SQL WHERE 子句相同。

ORDER BY 可以隨意對數據進(jìn)行排序。

RETURN 從過(guò)濾和排序后的 FLWOR 表達式返回最終結果集。

FLWOR 與 XMLQuery() 協(xié)作。以下是查詢(xún)和連接兩個(gè)文檔的示例:用 Party 鍵將 partys.xml 連接到 orders.xml 文檔。該 XML 數據位于 Oracle XML DB 信息庫中。為此,我們將使用 XMLQuery();FLWOR;以及 XQuery 函數 doc、count、avg 和 integer。它們位于內置 XQuery 函數的命名空間中,http://www.w3.org/2003/11/xpath_functions。

以下查詢(xún)讀取結果如下所示:使用函數 fn:doc,對于 (FOR) partys.xml 中的所有 partyno 屬性,連接 (LET) orders.xml 中匹配 partyno 的所有定單元素(變量 $p 綁定在 FOR 語(yǔ)句中)。這將生成一個(gè)項流($p 和 $o),其中 $p 表示一方的編號,而 $o 表示該方的一組定單。獲取其中 (WHERE) 有多個(gè)定單的項。使用命名空間 fn 中的 XQuery 函數 avg 對平均數 amt 進(jìn)行降序排序 (ORDER BY)。 Amt 附加到定單元素 $o。返回該方的編號(綁定到 $p)和子元素定單計數。

SELECT XMLQuery()(‘for $p in fn:doc("/public/partys.xml")/partys/party/@partynolet $o := fn:doc("/public/orders.xml")/orders/order[@partyno = $p]where fn:count($o) > 1order by fn:avg($o/@amt) descendingreturn <big-party>{$p,<ordercount>{fn:count($o)}</ordercount>,<avgamt>{xs:integer(fn:avg($o/@amt))}</avgamt>}</big-party>‘RETURNING CONTENT) ORDERS FROM DUAL;ORDERS<big-party>1111<ordercount>2</ordercount><avgamt>3500</avgamt></big-party>

是的,該查詢(xún)正在進(jìn)行大量工作并在 XML 文檔上顯示使用 FLWOR 表達式時(shí)可能出現的結果。

XQuery ora:函數

Oracle XML DB 提供五個(gè)開(kāi)發(fā)人員可以使用的 XQuery 函數。它們在 http://xmlns.oracle.com/xdb 命名空間中實(shí)現,該命名空間使用前綴 ora:。除此之外還有另外兩個(gè) XPath 函數。它們仍然不是 SQL/XML 標準的一部分,但預期將來(lái)會(huì )是。該 ora:view 函數是一個(gè)特別有價(jià)值的函數,可用于將關(guān)系數據轉換為 XML 格式。下面將對所有這些函數進(jìn)行介紹。

ora:view XQuery 函數。這是在關(guān)系表上創(chuàng )建視圖的有用函數。這可以使它們看起來(lái)像 XML 文檔。

Syntax: 	ora:view ([db-schema STRING, ] db_table STRING)RETURNS document-node (element())

本文稍后將給出使用 ora:view 的示例。

ora:contains XQuery 函數。命名空間前綴“ora:”和名稱(chēng)“contains”一起使用可創(chuàng )建 XPath 函數,該函數可用作 SQL/XML existsNode、extract 和 extractValue 函數的 XPath 參數。這使您能夠使用文本謂詞執行結構搜索。

如果 text_query 與 input_text 匹配,該函數將返回一個(gè)正數。如果它們不匹配,則返回 0。當它們與 existsNode、extract 或 extractValue 一起使用時(shí),您需要包括命名空間映射參數 xmlns:ora="http://xmlns.oracle.com/xdb"。ora:contains 的語(yǔ)法如下所示。當未定義 policy_owner 時(shí),所有者是當前用戶(hù)。policy_name 是要應用的匹配規則的名稱(chēng)。默認的匹配規則由 ctxsys.default_policy_oracontains 定義。

Syntax: ora:contains (input_text, text_query [, policy_name] [, policy_owner])

下面的示例顯示了如何使用 ora:contains 作為 existsNode 的參數。

SELECT count(*) FROM invoicexml_tblWHERE existsNode(object_value, ‘/Invoice/MailAddressTo/Person[ora:contains(text(), "Joe Smith") > 0]‘,‘xmlns:ora="http://xmlns.oracle.com/xdb"‘) = 1;COUNT(*)1

ora:matches XQuery 函數。該函數使用正則表達式匹配文本。這類(lèi)似于 SQL REGEXP_LIKE 條件,但是它使用 XQuery 參數而非 SQL 數據類(lèi)型。如果 target_string 匹配正則表達式 match_pattern,則返回 True;否則,返回 False。正如您在下面語(yǔ)法中所見(jiàn),可以添加 match_parameter 以指定在搜索中使用的附加標準。以下示例是提供區分大小寫(xiě)。

Syntax: ora:matches (target_string, match_pattern [, match_parameter])

ora:replace XQuery 函數。該函數在滿(mǎn)足 match_pattern 的情況下 (True) 使用 replace_string 替換 target_string,這是對 ora:matches 函數的擴展。與使用 ora:matches 一樣,使用正則表達式來(lái)匹配文本。

Syntax: ora:replace (target_string, match_pattern,replace_string [, match_parameter])

ora:sqrt XQuery 函數。顧名思義,該函數返回提供數字的平方根值。

Syntax: ora:sqrt (number)

XPath 擴展函數:ora:instanceof 和 ora:instanceof-only。當知道屬性和元素的數據類(lèi)型時(shí),Oracle XML DB 可以支持基于模式的數據。由于 XPath 1.0 不知道數據類(lèi)型信息,因此在命名空間 http://xmlns.oracle.com/xdb 中有 XML DB 擴展函數,它們使您能夠將 XML 文檔節點(diǎn)限制為特定數據類(lèi)型。函數 ora:instanceof 可用于將節點(diǎn)限制為數據類(lèi)型或子類(lèi)型,而 ora:instanceof-only 只將節點(diǎn)限制為數據類(lèi)型。子類(lèi)型是用于擴展或限制類(lèi)型的特性。

Syntax: ora:instanceof(nodeset-expr, typename [, schema-url])Syntax: ora:instanceof-only(nodeset-expr, typename [, schema-url])

在上面的語(yǔ)法中,nodeset-expr 通常是一個(gè)相關(guān)的 XPath 表達式。如果任何節點(diǎn)的數據類(lèi)型與類(lèi)型名匹配,則該函數返回 True,否則返回 False。類(lèi)型名可使用命名空間前綴限定。

對于非基于模式的數據,這些函數將返回 False,因為這些數據沒(méi)有與元素和屬性相關(guān)的數據類(lèi)型。

使用 fn:doc 和 fn:collection 函數在 XML DB 信息庫中查詢(xún) XML 數據

有兩個(gè)重要的 XQuery 函數可用于在 XML DB 信息庫中查詢(xún)所有資源。Fn:doc 是一個(gè) XQuery 函數,可以獲取包含 XML 數據的信息庫文件。該文件資源由其 URL 參數指出。XQuery 變量可以使用 FLWOR 表達式 FOR 和 LET 綁定到數據。XQuery 函數 fn:doc 可用于讀取存儲在 XML DB 信息庫中的單個(gè) XML 文檔。

在信息庫中查詢(xún)資源的第二個(gè) XQuery 函數是 fn:collection。該函數可以返回存儲在信息庫中同一文件夾中的大量類(lèi)似文檔。

現在,我們將通過(guò)創(chuàng )建信息庫資源來(lái)演示 fn:doc 和 fn:collection 如何處理一些簡(jiǎn)單示例。首先,使用 DBMS_XDB PL/SQL 程序包創(chuàng )建一個(gè)資源。這可用于在 XML DB 中管理資源。該 createResource 過(guò)程在本例中用于創(chuàng )建包含 Orders 和 Partys XML 文檔的新文件資源。

創(chuàng )建用于以下示例的定單和定方資源名。其中有一個(gè)名為 ordersnamespace.xml 的附加資源,它是一個(gè)使用命名空間的示例。

DECLAREres BOOLEAN;ordersxmlstring VARCHAR2(500):=‘<?xml version="1.0"?><orders><order orderno="15" partyno="1111" itemname="Widget" amt="5000"/><order orderno="25" partyno="1111" itemname="Do dad" amt="2000"/><order orderno="35" partyno="2222" itemname="All purpose item" amt="7000"/><order orderno="45" partyno="3333" itemname="The best thing" amt="15000"/></orders>‘;partysxmlstring VARCHAR2(500):=‘<?xml version="1.0"?><partys><party partyno="1111" partyname="ABC Corp" partycity="Toronto"/><party partyno="2222" partyname="Freds Inc" partycity="Chicago"/><party partyno="3333" partyname="Gofaster Corp" partycity="Montreal"/></partys>‘;ordersxmlnsstring VARCHAR2(500):=‘<?xml version="1.0"?><orders xmlns="http://order.com"><order orderno="15" partyno="1111" itemname="Widget" amt="5000"/><order orderno="25" partyno="1111" itemname="Do dad" amt="2000"/><order orderno="35" partyno="2222" itemname="All purpose item" amt="7000"/><order orderno="45" partyno="3333" itemname="The best thing" amt="15000"/></orders>‘;BEGINres := DBMS_XDB.createResource(‘/public/orders.xml‘,   ordersxmlstring);res := DBMS_XDB.createResource(‘/public/partys.xml‘,  partysxmlstring);res := DBMS_XDB.createResource(‘/public/ordersnamespace.xml‘, ordersxmlnsstring);END;

我們可以看到剛剛通過(guò)查詢(xún) resource_view 創(chuàng )建的資源,如下所示:

SQL>  select any_path, res from resource_view where any_path like ‘%partys%‘;ANY_PATHRES/public/partys.xml<Resource xmlns="http://xmlns.oracle.com/xdb/XDBResource.xsd"><CreationDate>2006-06-19T17:12:00.414000</CreationDate><ModificationDate>2006-06-19T17:12:00.414000</ModificationDate><DisplayName>partys.xml</DisplayName><Language>en-US</Language><CharacterSet>WINDOWS-1252</CharacterSet><ContentType>text/xml</ContentType><RefCount>1</RefCount></Resource>

接下來(lái),使用 fn:doc 顯示單個(gè) partys.xml 文檔。

SELECT XMLQuery(‘for $p in fn:doc("/public/partys.xml")return $p‘RETURNING CONTENT) partys FROM DUAL;PARTYS---------------------------------------------------------------------<partys><party partyno="1111" partyname="ABC Corp"partycity="Toronto"/><party partyno="2222" partyname="Freds Inc"partycity="Chicago"/> <party partyno="3333" partyname="Gofaster Corp"partycity="Montreal"/></partys>

對 Fn:collection 的使用與 fn:doc 稍有不同,它可返回存儲在信息庫中同一文件夾中的所有文檔。從該語(yǔ)句生成的輸出不適合打印,手動(dòng)進(jìn)行以下格式化以使該文檔可讀性更高。

SELECT XMLQuery(‘for $p in fn:collection("/public")return $p‘RETURNING CONTENT) collection_public FROM DUAL;COLLECTION_PUBLIC----------------------------------------------------------------------<orders><order orderno="15" partyno="1111" itemname="Widget" amt="5000"/><order orderno="25" partyno="1111" itemname="Do dad" amt="2000"/><order orderno="35" partyno="2222" itemname="All purpose item" amt="7000"/><order orderno="45" partyno="3333" itemname="The best thing" amt="15000"/></orders><orders xmlns="http://order.com"><order orderno="15" partyno="1111" itemname="Widget" amt="5000"/><order orderno="25" partyno="1111" itemname="Do dad" amt="2000"/><order orderno="35" partyno="2222" itemname="All purpose item" amt="7000"/><order orderno="45" partyno="3333" itemname="The best thing" amt="15000"/></orders><partys><party partyno="1111" partyname="ABC Corp" partycity="Toronto"/><party partyno="2222" partyname="Freds Inc" partycity="Chicago"/><party partyno="3333" partyname="Gofaster Corp" partycity="Montreal"/></partys>

還有其他大量 DBMS_XDB 過(guò)程和函數可用于管理所有 XML DB 資源,例如,提供刪除資源和創(chuàng )建文件夾的功能。這些函數可在 OTN 上的 Oracle XML DB 開(kāi)發(fā)人員指南 10g 第 2 版 中找到。

XMLQuery() 和 XMLTable()

Oracle 數據庫 10g 第 2 版中引入了 XMLQuery() 和 XMLTable() 函數。它們在 SQL 和 XML 之間提供了強大的接口,允許我們查詢(xún)、構造和轉換關(guān)系數據,就像它是 XML,反之也可以將 XML 數據當作關(guān)系數據來(lái)處理。通常,我們使用 XMLQuery() 從關(guān)系數據生成 XML 文檔,并使用 XMLTable() 從 XML 數據創(chuàng )建關(guān)系視圖。它們仍然不是 ANSISQL 的一部分,但預計會(huì )包括在將來(lái)的標準中。

XMLQuery() 函數。該函數用于構造 XML 數據并使用 XQuery 來(lái)查詢(xún)該數據。它支持在 SQL 上下文中執行 XQuery 表達式。我們也可以通過(guò)使用 ora:view 為關(guān)系數據創(chuàng )建動(dòng)態(tài) XML 視圖來(lái)查詢(xún)關(guān)系數據,并能夠操作部分 XML 文檔而非整個(gè)文檔。

XMLQuery() 將 XQuery 表達式作為字符串文字,將可選的 XQuery“上下文項”作為 SQL 表達式。該表達式設置將在其中評估 XQuery 表達式的 XPath 上下文。該函數將 XQuery 表達式結果作為 XMLType 實(shí)例返回。XMLQuery() 函數也可以將 SQL 表達式作為參數,其中當評估表達式時(shí),值綁定到 XQuery 變量。這些結果作為 XMLType 實(shí)例返回。

來(lái)看兩個(gè)示例,其中我們針對關(guān)系數據和 XML 數據使用了 XMLQuery()。

將 XMLQuery() 與 ora:view 和 FLWOR 表達式合并的示例。在第一個(gè)示例中,我們將在物理關(guān)系表上使用 XMLQuery()。XMLQuery() 必須操作 XML 數據,這可通過(guò)使用 HR 模式中關(guān)系表 Employee 和 Department 上的 ora:view 特性完成。當 ora:view 用在這兩個(gè)關(guān)系表上之后,它們將顯示為 XML,然后我們就能夠使用 XQuery 表達式,包括嵌套的 FLWOR 表達式。

下面的查詢(xún)正在進(jìn)行以下操作:對于每個(gè)部門(mén),獲取部門(mén) id,對于匹配部門(mén) id 且傭金高于 30% 的雇員,返回雇員的名和姓。請注意,FOR 表達式在該查詢(xún)中使用了兩次。

SELECT XMLQuery(‘FOR $dep in ora:view("DEPARTMENTS")/ROWRETURN <Department id="{$dep/DEPARTMENT_ID}"><Employee>{FOR $emp in ora:view("EMPLOYEES")/ROWWHERE $emp/DEPARTMENT_ID eq $dep/DEPARTMENT_IDand $emp/COMMISSION_PCT > .3RETURN ($emp/FIRST_NAME, $emp/LAST_NAME)}</Employee></Department>‘RETURNING CONTENT) HIGH_COMMISSION_EMP_NAMES FROM DUAL;HIGH_COMMISSION_EMP_NAMES---------------------------------------------------------------<Department id="10"><Employee></Employee></Department><Departmentid="20"><Employee></Employee></Department><Departmentid="30"><Employee></Employee></Department><Departmentid="40"><Employee></Employee></Department><Departmentid="50"><Employee></Employee></Department><Departmentid="60"><Employee></Employee></Department>

正如您所見(jiàn),結果不適合打印。該查詢(xún)語(yǔ)法有點(diǎn)復雜,但它顯示出我們能夠使用 ora:view 將關(guān)系數據轉換為 XML,并能夠針對 XML 文檔執行連接操作以及將謂詞應用到文檔中的數據上。

將 XMLQuery() 與 XMLType 列和 FLWOR 表達式一起使用的示例。表 invoicexml_col(我們在上面創(chuàng )建的,并在其中插入了一個(gè)文檔)包含一個(gè) XMLType 列 inv_doc。存儲在該列中的 Invoice 數據是 XML 格式的。在該查詢(xún)中,我們使用具有 PASSING 子句的 XMLQuery() 函數將 XMLType 列 inv_doc 傳遞到 XQuery。請注意我們是如何從基于 WHERE 謂詞的 Invoice 文檔返回一些特定字段的。實(shí)際上,我們能夠進(jìn)入 XML 文檔并根據謂詞檢索特定字段,而非只能夠將此文檔作為 CLOB 查看。

下面的 SELECT 語(yǔ)句適用于 invoicexml_col 的所有行。然后我們可以使用 FOR 語(yǔ)句迭代所有發(fā)票行。WHERE 謂詞取出 Zipcode 12345 的元素,然后返回 City、State 和 Zipcode,以及是否為 Zipcode 輸入了正確的 City 和 State。 IF…THEN…ELSE 構造將體現該語(yǔ)法的一些附加功能。

Select XMLQuery(‘FOR $i in /InvoiceWHERE  $i/MailAddressTo/Zipcode = 12345RETURN <Details><Zipcode num="{$i/MailAddressTo/Zipcode}"/><CityName char="{$i/MailAddressTo/City}"/><City>{IF ($i/MailAddressTo/City = "New York")THEN "Correct City"ELSE "Incorrect City"}</City><State>{if ($i/MailAddressTo/State = "NY")then "Correct State" else "Incorrect State"}</State></Details>‘PASSING inv_doc RETURNING CONTENT) ny_invoiceFROM invoicexml_col;NY_INVOICE<Details><Zipcode num="12345"></Zipcode><CityName char="New York"></CityName><City>Correct City</City><State>Correct State</State></Details>

這兩個(gè)查詢(xún)闡釋了我們必須以詳細的分段方式查看和處理 XML 文檔的功能。提供的功能類(lèi)似于我們用關(guān)系數據進(jìn)行的操作 — 令人驚奇!

XMLTable() 函數。該函數支持將 XML 值解釋為表或集。它用于從 XQuery 表達式的評估返回表和列,而不是像通常那樣返回一個(gè)序列作為 XQuery??梢圆樵?xún) XMLType 數據并將 XML 結果分割或分解為關(guān)系格式 — 可將其看作是創(chuàng )建一個(gè)虛擬表。然后,可以使用該虛擬表將數據插入到其他表中,或者查詢(xún)該虛擬表。關(guān)系視圖也可以針對 XML 數據進(jìn)行構造。XMLTable() 函數也可用在 SQL From 子句中。

將 XMLTable() 與 COLUMNS 子句一起使用的示例。我們將使用前面介紹過(guò) invoicexml_col 表來(lái)闡釋如何使用 XMLTable() 將 XML 數據轉換為關(guān)系格式。在下面的示例中,XMLTable() 訪(fǎng)問(wèn)存儲在列 inv_doc 中的 Invoice 文檔。使用 COLUMNS 子句將所需數據元素的路徑映射到新的名稱(chēng)和格式。XMLTable() 函數返回數據作為虛擬表,該查詢(xún)的結果與我們已經(jīng)查詢(xún)過(guò)的關(guān)系表一樣。請注意,通過(guò)在該查詢(xún)底部使用的 WHERE 子句,我們可以過(guò)濾 XML 數據,過(guò)濾的方式與使用任何為關(guān)系數據編寫(xiě)的 SQL 查詢(xún)的方式完全相同。

該查詢(xún)和輸出如下所示:

SELECT inv_id, a.PersonName, a.StreetName, a.CityName, a.State, a.ZipcodeFROM invoicexml_col,XMLTABLE(‘/Invoice‘PASSING invoicexml_col.inv_docCOLUMNSPersonName varchar2(10) PATH ‘/Invoice/MailAddressTo/Person‘,StreetName varchar2(20) PATH ‘/Invoice/MailAddressTo/Street‘,CityName varchar2(10) PATH ‘/Invoice/MailAddressTo/City‘,State varchar2(5) PATH ‘/Invoice/MailAddressTo/State‘,Zipcode varchar2(7) PATH ‘/Invoice/MailAddressTo/Zipcode‘) aWHERE a.CityName like ‘New%‘;INV_ID	PERSONNAME	STREETNAME	     CITYNAME	STATE 	ZIPCODE1	Joe Smith  	10 Apple Tree Lane      New York	 NY	 12345

執行 XML

如文中所述,我們已經(jīng)可以執行查看 XML 文檔的查詢(xún)。下一步是考慮使這些查詢(xún)快速執行的方式??梢越忉?XML 查詢(xún)并創(chuàng )建索引來(lái)幫助提高 XML 數據訪(fǎng)問(wèn)的性能。特別地,我們能夠以類(lèi)似過(guò)去調整 SQL 的方式改善 XPath 函數的性能。此外,對于 SQL 調整,在某些情況中,重構 XML 查詢(xún)也有助于更改和改進(jìn)訪(fǎng)問(wèn)路徑。

基于函數的索引可用在結構化和非結構化的 XMLType 表上,無(wú)論它們是否基于模式。我們還可能想對諸如 existsNode 的函數利用二進(jìn)制索引,即根據謂詞評估為 True 或 False 而只返回標志 0 或 1。

在本節中,我們將通過(guò)示例來(lái)了解一下結構化和非結構化索引通過(guò)解釋計劃會(huì )對性能產(chǎn)生怎樣的潛在影響。首先,優(yōu)化 XQuery 表達式,該表達式針對關(guān)系表使用 ora:view。

用 XQuery 表達式優(yōu)化關(guān)系數據。以下是一個(gè)調整示例,其中使用的是已分析過(guò)的類(lèi)似查詢(xún)。該查詢(xún)使用 ora:view 訪(fǎng)問(wèn)關(guān)系數據并利用 FLWOR 表達式。連接 HR 模式的關(guān)系表 Employees 和 Departments,并針對 commission_pct 大于 3 的所有員工返回部門(mén)信息。請注意,屬性名(例如,$emp/ROW/COMMISSION_PCT 中的 JOB)區分大小寫(xiě)。

在下面的查詢(xún)中,FOR 允許我們在 Departments 中迭代行元素 Employees。Employees 行綁定到變量 $emp,而 Departments 行綁定到 $dep。WHERE 執行這兩個(gè)表的連接,并選擇 commission_pct 大于 3 的所有員工。RETURN 返回部門(mén)信息。

該查詢(xún)和解釋計劃如下所示:

explain plan forSELECT XMLQuery(‘for $emp in ora:view("EMPLOYEES"), $dep in ora:view("DEPARTMENTS")where $emp/ROW/DEPARTMENT_ID = $dep/ROW/DEPARTMENT_IDand $emp/ROW/COMMISSION_PCT > .3return $dep‘RETURNING CONTENT) AS high_commission_employeesFROM DUAL;QUERY_PLAN              OBJECT_NAME	         COST     BYTES	LEVELSELECT STATEMENT                               2                  1SORT                                                 82         2HASH JOIN                                  5       328        3TABLE ACCESS      EMPLOYEES              2       104        4TABLE ACCESS      DEPARTMENTS            2       1512       4FAST DUAL                                    2                  2

如您所見(jiàn),優(yōu)化程序選擇的訪(fǎng)問(wèn)路徑不使用索引。由于 ora:view 允許我們將關(guān)系查詢(xún)的結果返回為 XML 元素,因此我們完全可以在關(guān)系表上創(chuàng )建 b 樹(shù)索引并查看這是否可以提高性能。

Create index emp_idx1 on employees (department_id, commission_pct);Create index dept_idx1 on departments (department_id);QUERY_PLAN          OBJECT_NAME		COST     BYTES	LEVELSELECT STATEMENT                               2                  1SORT                                                 82         2TABLE ACCESS    DEPARTMENTS                1       56         3NESTED LOOPS                               2       328        4INDEX           EMP_IDX1                   1       104        5INDEX           DEPT_IDX1                  0                  5FAST DUAL                                    2                  2

現在,這些索引獲得了使用,成本略有降低。我們使用 ora:view 對 XQuery 的調整非常類(lèi)似于對標準的非 XML SQL 的調整。對于標準 SQL,重寫(xiě)該查詢(xún)并使用諸如綁定變量(而非硬編碼的字符串值)的特性將有助于提高性能。

優(yōu)化結構化 XMLType 數據。XPath 重寫(xiě)可以?xún)?yōu)化結構化(對象關(guān)系)存儲技術(shù)。該優(yōu)化程序可以進(jìn)行另一個(gè)內部性能改進(jìn):當以下內容為真時(shí),它可以將基于 XPath 的函數更改為關(guān)系語(yǔ)句:

  • XMLType 數據使用一個(gè)注冊的 XMLSchema。這是使用基于模式的數據的另一個(gè)優(yōu)勢。
  • 屬性映射為基礎 SQL(關(guān)系)表。
  • 使用了結構化存儲。

這提供了由于性能原因進(jìn)行查詢(xún)重寫(xiě)的可能性。它也允許使用關(guān)系性能調整技術(shù),如上所示。

現在,我們優(yōu)化針對結構化、非關(guān)系 XMLType 數據的查詢(xún)。首先看一個(gè)非常簡(jiǎn)單的示例,它使用早前創(chuàng )建的 invoicexml_tbl 表。

explain plan forselect extract(object_value, ‘/Invoice/MailAddressTo‘)from invoicexml_tblwhere extractValue(object_value, ‘/Invoice/MailAddressTo/Person‘)= ‘Joe Smith‘;The access path is shown below.QUERY_PLAN        OBJECT_NAME          COST      BYTES	LEVELSELECT STATEMENT                        3        87       1TABLE ACCESS    INVOICEXML_TBL        3        87       2

可以創(chuàng )建該查詢(xún)中使用的針對謂詞的基于函數的索引。該索引必須使用與將使用它的查詢(xún)完全相同的語(yǔ)法。該索引將創(chuàng )建并多次解釋 SQL 以查看是否使用了新索引。

Create index invoicexml_tbl_idx1 on invoicexml_tbl(extractValue(object_value, ‘/Invoice/MailAddressTo/Person‘));QUERY_PLAN        OBJECT_NAME           COST    BYTES	LEVELSELECT STATEMENT                         1      87        1TABLE ACCESS    INVOICEXML_TBL         1      87        2INDEX           INVOICEXML_TBL_IDX1    1                3

使用了新的基于函數的索引后,查詢(xún)成本將減少。

優(yōu)化非結構化 XMLType 數據。
現在我們將執行與非結構化 XMLType 數據相同的測試。表 invtest_unstruct 的創(chuàng )建方式將與我們創(chuàng )建 invoicexml_tbl 的方式完全相同,但我們會(huì )添加“XMLType store as CLOB”語(yǔ)法以確保將它定義為非結構化數據。數據定義語(yǔ)言 (DDL)、插入和解釋計劃如下所示:

create table invtest_unstruct of XMLtypeXMLType store as CLOB;Insert into invtest_unstruct values (XMLType(bfilename(‘XMLDIR‘, ‘invoicexml.txt‘),nls_charset_id(‘WE8MSWIN1252‘) ));explain plan forselect extract(object_value, ‘/Invoice/MailAddressTo‘)from invtest_unstructwhere extractValue(object_value, ‘/Invoice/MailAddressTo/Person‘)=‘Joe Smith‘/QUERY_PLAN            OBJECT_NAME      	COST     BYTES	LEVELSELECT STATEMENT                               2       2002       1TABLE ACCESS        INVTEST_UNSTRUCT         2       2002       2

現在,我們將創(chuàng )建一個(gè)基于函數的索引,來(lái)查看是否將使用它以及是否減少了預期的成本。請注意,“create index”語(yǔ)法與查詢(xún)謂詞中使用的語(yǔ)法相同。

Create index invtest_unstruct_idx1 on invtest_unstruct(extractValue(object_value, ‘/Invoice/MailAddressTo/Person‘));QUERY_PLAN           OBJECT_NAME              COST     BYTES 	LEVELSELECT STATEMENT                               1       2002	  1TABLE ACCESS       INVTEST_UNSTRUCT          1       2002   2INDEX              INVTEST_UNSTRUCT_IDX1     1           	  3

正如您看到的,相同的索引和查詢(xún)可以有效用于結構化和非結構化數據。但需要注意到,結構化數據訪(fǎng)問(wèn)通常比非結構化訪(fǎng)問(wèn)更高效。

結論

Oracle 數據庫已經(jīng)快速發(fā)展為將 XML 標準與數據合并在內。Oracle9i 數據庫引入了 XML DB 信息庫和一個(gè)新數據類(lèi)型 XMLType,后者提供 LOB 以及結構化存儲選項。利用 Oracle XML DB 特性,通過(guò)將 URI 映射為數據庫對象的層次模型,您能夠在數據庫中執行本機 XML 處理。通過(guò)使用節點(diǎn)和路徑概念的“邏輯樹(shù)”,可使用 XPath 表達式操作文檔的單個(gè)元素。Oracle9i 數據庫中還包括 XMLSchema 支持。

Oracle 數據庫 10g 通過(guò) W3C XML XQuery 語(yǔ)言增強了 XML 支持,該語(yǔ)言包括 XMLQuery() 和 XMLTable() 函數。這些特性的組合簡(jiǎn)化了 Oracle 數據庫 10g 第 2 版中關(guān)系數據和 XML 數據間的相互轉換使用。正如本文所述,SQL 查詢(xún)可以操作 XML 數據,而 XML 查詢(xún)現在能夠訪(fǎng)問(wèn)關(guān)系數據。其中的關(guān)鍵是 Oracle 對 XMLQuery() 和 XMLTable() 的 SQL/XML 實(shí)現。

Oracle 的基于標準的方法也支持流行的協(xié)議(例如,FTP、HTTP 和 WebDAV),以便允許常用客戶(hù)端工具和應用程序訪(fǎng)問(wèn)、編輯和發(fā)布存儲在數據庫中的 XML 數據。

通過(guò)本文,您可輕松增強自己在處理關(guān)系數據時(shí)獲取的技巧,進(jìn)而使用這些 SQL/XML 特性來(lái)處理 XML。其中重要的一點(diǎn)是,我們能夠通過(guò) Oracle 的索引、解釋和存儲特性來(lái)提高 XML 數據訪(fǎng)問(wèn)的性能。對于設計人員、開(kāi)發(fā)人員和 DBA 來(lái)說(shuō),及時(shí)了解這個(gè)快速變化的技術(shù)是很關(guān)鍵的。


Tim Quinlan [tquinlan@tlqconsulting.com] 是一名 Oracle 認證的數據庫管理員。他從 1981 年就開(kāi)始從事數據庫工作,從 Oracle 7 到 Oracle10g 第 2 版均有接觸。擔任過(guò)企業(yè)級數據倉庫和事務(wù)數據庫的 DBA、架構師、設計者和實(shí)現者。Tim 在許多會(huì )議上發(fā)表過(guò)演講,教授過(guò)數據庫課程,并為很多暢銷(xiāo)的數據庫出版物撰寫(xiě)過(guò)專(zhuān)題文章。他的主要(專(zhuān)業(yè))興趣是設計和實(shí)現高性能、高可用性的大型數據庫系統。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
XML數據庫:最新進(jìn)展和發(fā)展方向
Oracle XMLTable 使用教程與實(shí)例
高級SQL優(yōu)化(二)
利用 Oracle 10g 技能學(xué)習 DB2 9.1 for Linux, UNIX an...
DB2和Oracle區別
盧濤:充分利用數據庫功能實(shí)現高效數據批量審核
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

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