• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            內(nèi)容摘要:可以利用 XQuery 和 DB2 9 檢索 XML 列中存儲(chǔ)的整個(gè) XML 文檔或 XML 片段。還可以為查詢指定基于 XML 的過濾器、對(duì) XML 輸出進(jìn)行轉(zhuǎn)換以及將條件邏輯合并到查詢中。本教程介紹 DB2 的 XQuery 支持,解釋幾個(gè)基本的語言概念,并講解如何針對(duì) DB2 中存儲(chǔ)的 XML 數(shù)據(jù)編寫和執(zhí)行簡(jiǎn)單的 XQuery。

              XQuery 概述

              DB2 9 提供了對(duì) XQuery 的支持。XQuery 是一種專門為操作 XML 數(shù)據(jù)而設(shè)計(jì)的新的查詢語言,它是 W3C 行業(yè)標(biāo)準(zhǔn)的一部分。XQuery 使用戶能夠在 XML 文檔固有的層次結(jié)構(gòu)中導(dǎo)航。因此,可以使用 XQuery 檢索 XML 文檔或文檔片段。還可以編寫包含基于 XML 的謂詞的 XQuery,從而將不需要的數(shù)據(jù)從 DB2 將返回的結(jié)果中 “過濾出去”。XQuery 提供了許多其他功能,比如對(duì) XML 輸出進(jìn)行轉(zhuǎn)換以及將條件邏輯合并到查詢中。

              在學(xué)習(xí)如何使用 XQuery 之前,需要了解這種語言的一些基本概念。

              XQuery 基礎(chǔ)

              XQuery 總是將 XQuery Data Model 的一個(gè)值轉(zhuǎn)換為 XQuery Data Model 的另一個(gè)值。XQuery Data Model 中的一個(gè)值是由零個(gè)或更多條目組成的序列。條目可以是:

              任何原子值

              XML 節(jié)點(diǎn)(有時(shí)候稱為 XML 文檔片段),比如元素、屬性或文本節(jié)點(diǎn)

              完整的 XML 文檔

              XQuery 的輸入常常是一個(gè) XML 文檔集合。

              清單 1 顯示一個(gè) XML 文檔,其中包含 8 個(gè)元素節(jié)點(diǎn)、1 個(gè)屬性節(jié)點(diǎn)和 6 個(gè)文本節(jié)點(diǎn)。元素節(jié)點(diǎn)由元素標(biāo)記表示。在這個(gè)文檔中,Client、Address、street、city、state、zip 和兩個(gè) email 元素都是元素節(jié)點(diǎn)。如果仔細(xì)看看 Client 元素,就會(huì)發(fā)現(xiàn)它包含一個(gè)屬性節(jié)點(diǎn),客戶的 id。文檔的一些元素節(jié)點(diǎn)有相關(guān)聯(lián)的文本節(jié)點(diǎn)。例如,city 元素的文本節(jié)點(diǎn)是 San Jose。

            清單 1. 示例 XML 文檔
                      
            <Client id="123">
              <Address>
                <street>9999 Elm St.</street>
                <city>San Jose</city>
                <state>CA</state>
                <zip>95141</zip>
              </Address>
              <email>anyemail@yahoo.com</email>
              <email>anotheremail@yahoo.com</email>
            </Client>

              圖 1 顯示這個(gè)示例文檔中的節(jié)點(diǎn)。

            圖 1. 示例 XML 文檔中的元素、屬性和文本節(jié)點(diǎn)DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 7 部分: XQuery 簡(jiǎn)介

              XQuery 語言來源于 XPath(定義用戶如何在 XML 文檔中導(dǎo)航)和 XML Schema(讓用戶能夠?yàn)槲臋n指定有效的結(jié)構(gòu)和數(shù)據(jù)類型)等其他 XML 標(biāo)準(zhǔn)。在本教程中,學(xué)習(xí)如何將 XPath 表達(dá)式結(jié)合到 XQuery 中。

              XQuery 提供了幾種不同的表達(dá)式,可以按照自己喜歡的任何方式組合使用它們。每個(gè)表達(dá)式都返回一系列值,這些值可以用作其他表達(dá)式的輸入。最外層表達(dá)式的結(jié)果就是查詢的結(jié)果。

              本教程討論兩種重要的 XQuery 表達(dá)式:

            路徑表達(dá)式 允許用戶在 XML 文檔的層次結(jié)構(gòu)中導(dǎo)航(或者說 “漫游”)并返回在路徑末端找到的節(jié)點(diǎn)。 FLWOR 表達(dá)式 它很像 SQL 中的 SELECT-FROM-WHERE 表達(dá)式。它用來遍歷一系列條目并可選地返回每個(gè)條目的某些計(jì)算結(jié)果。

              XQuery 與 SQL 的差異

              許多 SQL 用戶誤認(rèn)為 XQuery 與 SQL 非常相似。但是,XQuery 在許多方面與 SQL 差異很大,因?yàn)樵O(shè)計(jì)這種語言的目的是操縱具有不同性質(zhì)的不同數(shù)據(jù)模型。XML 文檔包含層次結(jié)構(gòu)并有固有的次序。與之相反,關(guān)系 DBMS(或者更準(zhǔn)確地說,基于 SQL 的 DBMS)支持的表是平面的和基于集合的,所以行是無序的。

              數(shù)據(jù)模型中的這些差異使得用來支持它們的查詢語言有很大差異。例如,XQuery 使程序員能夠在 XML 的層次結(jié)構(gòu)中導(dǎo)航。一般的 SQL(不帶 XML 擴(kuò)展)沒有(也不需要)在表數(shù)據(jù)結(jié)構(gòu)中 “導(dǎo)航” 的表達(dá)式。XQuery 支持有類型數(shù)據(jù)和無類型數(shù)據(jù),而 SQL 數(shù)據(jù)總是要用特定的類型進(jìn)行定義。

              XQuery沒有空值(null),因?yàn)?XML 文檔忽略缺失的或未知的數(shù)據(jù)。SQL 使用空值表示缺失的或未知的數(shù)據(jù)。XQuery 返回 XML 數(shù)據(jù)的序列;SQL 返回各種 SQL 數(shù)據(jù)類型的結(jié)果集。最后,XQuery 只操作 XML 數(shù)據(jù)。SQL 操作按照傳統(tǒng) SQL 類型定義的列,SQL/XML(帶 XML 擴(kuò)展的 SQL)操作 XML 數(shù)據(jù)和傳統(tǒng)類型的 SQL 數(shù)據(jù)。

              XQuery 中的路徑表達(dá)式

              XQuery 支持 XPath 表達(dá)式,使用戶能夠在 XML 文檔層次結(jié)構(gòu)中導(dǎo)航,找到他們所需要的部分。詳細(xì)討論 XPath 超出了本教程的范圍,但是我們?cè)谶@里要看幾個(gè)簡(jiǎn)單的示例。

              XPath 表達(dá)式看起來非常像在操作傳統(tǒng)計(jì)算機(jī)文件系統(tǒng)時(shí)使用的表達(dá)式。考慮一下在 Unix 或 Windows 目錄中是如何導(dǎo)航的,就能夠理解使用 XPath 在 XML 文檔中進(jìn)行導(dǎo)航的方式。

              XQuery 中的路徑表達(dá)式由一系列 “步” 組成,步之間由斜線字符分隔。在最簡(jiǎn)單的形式中,每一步在 XML 層次結(jié)構(gòu)中下降一層,尋找前一步返回的元素的子元素。路徑表達(dá)式中的每一步還可以包含一個(gè)謂詞,它對(duì)這一步返回的元素進(jìn)行過濾,只保留滿足條件的元素。稍后將看到這樣的一個(gè)示例。

              一種常見的任務(wù)是從 XML 文檔根(XML 層次結(jié)構(gòu)的最頂層)開始導(dǎo)航,尋找感興趣的某個(gè)節(jié)點(diǎn)。例如,要想獲得清單 1 的文檔中的 email 元素,可以編寫下面的表達(dá)式:

            清單 2. 導(dǎo)航到 email 元素
                      
            /Client/email

              如果文檔包含多個(gè) email 元素,而您只想獲得第一個(gè),那么可以編寫:

            清單 3. 導(dǎo)航到第一個(gè) email 元素
                      
            /Client/email[1]

              除了在路徑表達(dá)式中指定元素節(jié)點(diǎn)之外,還可以使用 @ 符號(hào)指定屬性節(jié)點(diǎn),從而在元素中識(shí)別出屬性。下面這個(gè)路徑表達(dá)式導(dǎo)航到 id 屬性等于 123 的 Client 元素中的第一個(gè) email 元素:

            清單 4. 指定屬性節(jié)點(diǎn)和值
                      
            /Client[@id='123']/email[1]

              前面這個(gè)示例使用了一個(gè)基于屬性值的過濾謂詞。還可以根據(jù)其他節(jié)點(diǎn)值進(jìn)行過濾。XPath 用戶常常根據(jù)元素值進(jìn)行過濾,比如下面的表達(dá)式返回住在加利福尼亞的客戶的 zip 元素:

            清單 5. 根據(jù)元素值進(jìn)行過濾
                      
            /Client/Address[state="CA"]/zip

              可以使用通配符(“*”)匹配路徑表達(dá)式中各個(gè)步上的任何節(jié)點(diǎn)。下面的示例獲取在 Client 元素的任何直接子元素下找到的任何 city 元素。

            清單 6. 使用通配符
                      
            /Client/*/city

              對(duì)于我們的示例文檔,這將返回值為 San Jose 的 city 元素。導(dǎo)航到這個(gè) city 元素的更精確的方法是:

            清單 7. 導(dǎo)航到 city 元素的更精確的方法
                      
            /Client/Address/city

              清單 8 給出幾個(gè)其他類型的路徑表達(dá)式示例。

            清單 8. 更多路徑表達(dá)式及其含義
                      
            //*            (獲取文檔中的所有節(jié)點(diǎn))
            //email          (尋找文檔中任何地方的 email 元素)
            /Client/email[1]/text()  (獲得 Client 元素下第一個(gè) email 元素的文本節(jié)點(diǎn))
            /Client/Address/*     (選擇根 Client 元素的 Address 子元素的所有子節(jié)點(diǎn))
            /Client/data(@id)     (返回 Client 元素的 id 屬性的值)
            /Client/Address[state="CA"]/../email  (尋找地址在加利福尼亞的客戶的 email 元素。
                    “..” 這一步導(dǎo)航回 Address 節(jié)點(diǎn)的父元素。)

              注意,XPath 是大小寫敏感的。在編寫 XQuery 時(shí)記住一點(diǎn)很重要,因?yàn)檫@是 XQuery 與 SQL 不同的一個(gè)方面。例如,如果將路徑表達(dá)式 “/client/address” 放進(jìn) XQuery,對(duì)于 清單 1 中的示例文檔,不會(huì)返回任何結(jié)果。

              XQuery 中的 FLWOR 表達(dá)式

              人們常常提到 XQuery 中的 FLWOR 表達(dá)式。與 SQL 中的 SELECT-FROM-WHERE 塊一樣,XQuery FLWOR 表達(dá)式可以包含多個(gè)由關(guān)鍵字指示的子句。FLWOR 表達(dá)式的子句以下面的關(guān)鍵字開頭:

              for:遍歷一個(gè)輸入序列,依次將一個(gè)變量綁定到每個(gè)輸入條目

              let:聲明一個(gè)變量并給它賦值,值可以是包含多個(gè)條目的列表

              where:指定對(duì)查詢結(jié)果進(jìn)行過濾的標(biāo)準(zhǔn)

              order by:指定結(jié)果的排序次序

              return:定義返回的結(jié)果

              我們來簡(jiǎn)要介紹一下每個(gè)關(guān)鍵字。我們將在一節(jié)中討論 for 和 return,所以可以看到一個(gè)完整的示例。(如果沒有 return 子句,表達(dá)式就不完整。)

            for 和 return for 和 return 關(guān)鍵字用來遍歷一系列值并為每個(gè)值返回某些結(jié)果。下面是一個(gè)非常簡(jiǎn)單的示例:
            for $i in (1, 2, 3)
            return $i

              在 XQuery 中,變量名前面有一個(gè)美元符號(hào)(“$”)。所以,前面的示例將數(shù)字 1、2 和 3 綁定到變量 $i(每次綁定一個(gè)數(shù)字),并對(duì)于每次綁定返回 $i 的值。前面表達(dá)式的輸出是 3 個(gè)值的序列:
            1
            2
            3

            let 有時(shí)候人們難以判斷什么時(shí)候應(yīng)該使用 let 關(guān)鍵字而不是 for。let 關(guān)鍵字并不像 for 關(guān)鍵字那樣遍歷一系列輸入,并將每個(gè)條目依次綁定到一個(gè)變量,而是將一個(gè)單一輸入值賦值給變量,但是這個(gè)輸入值可以是零個(gè)、一個(gè)或更多條目的序列。因此,在 XQuery 中 for 和 let 的行為差異很大。

              看一個(gè)示例應(yīng)該有助于澄清這一差異。請(qǐng)考慮下面這個(gè)使用 for 關(guān)鍵字的表達(dá)式,并注意返回的輸出:

            for $i in (1, 2, 3)
            return <output> {$i} </output>
            <output>1</output>
            <output>2</output>
            <output>3</output>

              表達(dá)式的最后一行要求為每次迭代返回一個(gè)名為 output 的新元素。這個(gè)元素的值是 $i 的值。因?yàn)?$i 依次設(shè)置為數(shù)字值 1、2 和 3,所以這個(gè) XQuery 表達(dá)式返回 3 個(gè) output 元素,它們具有不同的值。

              現(xiàn)在考慮使用 let 關(guān)鍵字的類似表達(dá)式:

            let $i := (1, 2, 3)
            return <output>{$i}</output>
            <output>1 2 3</output>

              輸出很不一樣。輸出只有一個(gè) output 元素,它的值是 “1 2 3”。

              這兩個(gè)示例說明了一個(gè)重點(diǎn):for 關(guān)鍵字遍歷輸入序列中的條目(每次一個(gè)),并將每個(gè)條目依次綁定到一個(gè)指定的變量。與之相反,let 關(guān)鍵字將輸入序列中的所有條目同時(shí)綁定到一個(gè)指定的變量。

            where 在 XQuery 中,where 的功能很像 SQL 中的 WHERE 子句:它使用戶能夠?qū)⑦^濾標(biāo)準(zhǔn)應(yīng)用于查詢。考慮以下示例:
            for $i in (1, 2, 3)
            where $i < 3
            return <output>{$i}</output>
            <output>1</output>
            <output>2</output>
            order by 使用戶能夠讓返回的結(jié)果按照指定的次序排序。考慮以下 XQuery 表達(dá)式和它的輸出(輸出沒有按照任何用戶指定的次序進(jìn)行排序):
            for $i in (5, 1, 2, 3)
            return $i
            5
            1
            2
            3

              可以使用 order by 關(guān)鍵字對(duì)結(jié)果進(jìn)行排序。下面的示例使返回的結(jié)果按照降序排序:
            for $i in (5, 1, 2, 3)
            order by $i descending
            return $i
            5
            3
            2
            1

              DB2 對(duì) XQuery 的支持

              DB2 把 XQuery 當(dāng)作一類語言,這允許用戶直接編寫 XQuery 表達(dá)式,而不需要將 XQuery 嵌入或包裝到 SQL 語句中。DB2 的查詢引擎將原生地處理 XQuery,這意味著它直接分析、評(píng)估和優(yōu)化 XQuery,而不需要在幕后將它們轉(zhuǎn)換為 SQL。如果愿意,可以編寫同時(shí)包含 XQuery 和 SQL 的 “多語種” 查詢。DB2 也會(huì)處理和優(yōu)化這些查詢。

              要在 DB2 中直接執(zhí)行 XQuery,必須在查詢前面加上關(guān)鍵字 xquery。這指示 DB2 調(diào)用它的 XQuery 分析器來處理請(qǐng)求。如果將 XQuery 作為最外層的(頂級(jí))語言使用,那么只需這么做就夠了。如果將 XQuery 表達(dá)式嵌入 SQL 中,那么不需要在前面加上 xquery 關(guān)鍵字。

              在本教程中,將以 XQuery 作為主要語言,所以這里給出的所有查詢都在開頭處加上 xquery 關(guān)鍵字。

              示例數(shù)據(jù)庫(kù)環(huán)境

              為了幫助您學(xué)習(xí) XQuery,本教程建立一個(gè)包含 XML 文檔的 “clients” 示例表。下面幾節(jié)詳細(xì)地解釋這個(gè)表及其內(nèi)容,并描述 DB2 提供的可以用來執(zhí)行 XQuery 的功能。

              如果希望在自己的 DB2 系統(tǒng)中設(shè)置這個(gè)示例表和內(nèi)容,那么可以使用腳本 tutorial.sql。它包含本節(jié)所示的所有代碼。

              示例表

              示例中的 clients 表包含幾個(gè)傳統(tǒng) SQL 數(shù)據(jù)類型(比如整數(shù)和可變長(zhǎng)度的字符串)的列,還有一個(gè)新的 SQL “XML” 數(shù)據(jù)類型的列。

              前三列記錄客戶的 ID、姓名和狀態(tài)信息。status 列的典型值包括 Gold、Silver 和 Standard。第四列包含每個(gè)客戶的聯(lián)系信息,比如家庭的郵政地址、電話號(hào)碼、電子郵件地址等等。這些信息存儲(chǔ)在良構(gòu)的 XML 文檔中。

              下面是 clients 表的定義:

            清單 9. clients 表的定義
                      
            create table clients(
            id     int primary key not null,
            name     varchar(50),
            status     varchar(10),
            contactinfo   xml
            );

              示例 XML 文檔

              在研究如何編寫針對(duì)這個(gè)表的 XQuery 之前,需要用一些示例數(shù)據(jù)填充它。下面的 SQL 語句將 6 行數(shù)據(jù)插入 clients 表。每行都包含一個(gè) XML 文檔,每個(gè) XML 文檔的結(jié)構(gòu)都有所不同。例如,有的客戶有電子郵件地址,而其他客戶沒有。

            清單 10. clients 表的示例數(shù)據(jù)
                      
            insert into clients values (3227, 'Ella Kimpton', 'Gold',
            '<Client>
              <Address>
                <street>5401 Julio Ave.</street>
                <city>San Jose</city>
                <state>CA</state>
                <zip>95116</zip>
              </Address>
              <phone>
                <work>4084630000</work>
                <home>4081111111</home>
                <cell>4082222222</cell>
              </phone>
              <fax>4087776666</fax>
              <email>love2shop@yahoo.com</email>
            </Client>'
            );
            insert into clients values (8877, 'Chris Bontempo', 'Gold',
            '<Client>
              <Address>
                <street>1204 Meridian Ave.</street>
                <apt>4A</apt>
                <city>San Jose</city>
                <state>CA</state>
                <zip>95124</zip>
              </Address>
              <phone>
                <work>4084440000</work>
              </phone>
              <fax>4085555555</fax>
            </Client>'
            );
            insert into clients values (9077, 'Lisa Hansen', 'Silver',
            '<Client>
              <Address>
                <street>9407 Los Gatos Blvd.</street>
                <city>Los Gatos</city>
                <state>CA</state>
                <zip>95032</zip>
              </Address>
              <phone>
                <home>4083332222</home>
              </phone>
            </Client>'
            );
            insert into clients values (9177, 'Rita Gomez', 'Standard',
            '<Client>
              <Address>
                <street>501 N. First St.</street>
                <city>Campbell</city>
                <state>CA</state>
                <zip>95041</zip>
              </Address>
              <phone>
                <home>4081221331</home>
                <cell>4087799881</cell>
              </phone>
              <email>golfer12@yahoo.com</email>
            </Client>'
            );
            insert into clients values (5681, 'Paula Lipenski', 'Standard',
            '<Client>
              <Address>
                <street>1912 Koch Lane</street>
                <city>San Jose</city>
                <state>CA</state>
                <zip>95125</zip>
              </Address>
              <phone>
                <cell>4085430091</cell>
              </phone>
              <email>beatlesfan36@hotmail.com</email>
              <email>lennonfan36@hotmail.com</email>
            </Client>'
            );
            insert into clients values (4309, 'Tina Wang', 'Standard',
            '<Client>
              <Address>
                <street>4209 El Camino Real</street>
                <city>Mountain View</city>
                <state>CA</state>
                <zip>95033</zip>
              </Address>
              <phone>
                <home>6503310091</home>
              </phone>
            </Client>'
            );

              查詢環(huán)境

              本教程中的所有查詢都設(shè)計(jì)為交互式地執(zhí)行。可以通過 DB2 命令行處理程序或 DB2 Control Center 的 DB2 Command Editor 執(zhí)行這些查詢。本教程中的示例使用 DB2 命令行處理程序。(DB2 還提供了基于 Eclipse 的 Developer Workbench,可以幫助您以圖形化方式構(gòu)造 XQuery,但是對(duì) Developer Workbench 的討論超出了本教程的范圍。)

              可以修改 DB2 命令行處理程序的默認(rèn)設(shè)置,以便更容易處理 XML 數(shù)據(jù)。例如,下面的命令(從一個(gè) DB2 命令窗口中發(fā)出)將以某種方式啟動(dòng) DB2 命令行處理程序,這種方式讓 XQuery 結(jié)果以容易閱讀的格式顯示:

            清單 11. 設(shè)置 DB2 命令行處理選項(xiàng)
                      
            db2 -i -d

              這個(gè)命令使 DB2 在顯示的 XQuery 結(jié)果中增加額外的空白。DB2 實(shí)際上并不將這些空白添加到數(shù)據(jù)中。應(yīng)用程序看到的返回條目中也沒有額外的空白 —— 這些空白只出現(xiàn)在 DB2 命令行處理程序窗口中。

              簡(jiǎn)單的 XML 數(shù)據(jù)檢索操作

              在本節(jié)中,將學(xué)習(xí)如何編寫檢索整個(gè) XML 文檔和 XML 文檔的特定部分(即片段)的 XQuery。為此,將使用 XPath 表達(dá)式和 FLWOR 表達(dá)式。

              檢索 DB2 中存儲(chǔ)的完整 XML 文檔

              在作為頂級(jí)語言運(yùn)行時(shí),XQuery 需要一個(gè)輸入數(shù)據(jù)的來源。在 DB2 中,指定輸入數(shù)據(jù)來源的一種方法是調(diào)用函數(shù) db2-fn:xmlcolumn。這個(gè)函數(shù)有一個(gè)輸入?yún)?shù),這個(gè)參數(shù)標(biāo)識(shí)用戶感興趣的 DB2 表和 XML 列。db2-fn:xmlcolumn 函數(shù)返回給定的列中存儲(chǔ)的 XML 文檔序列。例如,以下查詢返回包含客戶聯(lián)系信息的 XML 文檔序列:

            清單 12. 返回客戶聯(lián)系數(shù)據(jù)的簡(jiǎn)單 XQuery
                      
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')

              您可能會(huì)奇怪,為什么這個(gè)查詢中指定的表和列名是大寫的。如果回憶一下前面用來創(chuàng)建這個(gè)表的 SQL 語句,就會(huì)知道表和列名是小寫的。除非另外指定,DB2 會(huì)在內(nèi)部編目表中將表和列名轉(zhuǎn)換為大寫。因?yàn)?XQuery 是大小寫敏感的,所以小寫的表和列名與 DB2 編目中的大寫名稱不匹配。

              現(xiàn)在,考慮這個(gè) XQuery 的輸出。對(duì)于插入 clients 表的 示例數(shù)據(jù),清單 12 中查詢的輸出是 6 個(gè) XML 文檔,如下所示。

            清單 13. 前一個(gè)查詢的輸出
                      
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  5401 Julio Ave.
                </street>
                <city>
                  San Jose
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95116
                </zip>
              </Address>
              <phone>
                <work>
                  4084630000
                </work>
                <home>
                  4081111111
                </home>
                <cell>
                  4082222222
                </cell>
              </phone>
              <fax>
                4087776666
              </fax>
              <email>
                love2shop@yahoo.com
              </email>
            </Client>
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  1204 Meridian Ave.
                </street>
                <apt>
                  4A
                </apt>
                <city>
                  San Jose
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95124
                </zip>
              </Address>
              <phone>
                <work>
                  4084440000
                </work>
              </phone>
              <fax>
                4085555555
              </fax>
            </Client>
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  9407 Los Gatos Blvd.
                </street>
                <city>
                  Los Gatos
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95032
                </zip>
              </Address>
              <phone>
                <home>
                  4083332222
                </home>
              </phone>
            </Client>
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  501 N. First St.
                </street>
                <city>
                  Campbell
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95041
                </zip>
              </Address>
              <phone>
                <home>
                  4081221331
                </home>
                <cell>
                  4087799881
                </cell>
              </phone>
              <email>
                golfer12@yahoo.com
              </email>
            </Client>
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  1912 Koch Lane
                </street>
                <city>
                  San Jose
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95125
                </zip>
              </Address>
              <phone>
                <cell>
                  4085430091
                </cell>
              </phone>
              <email>
                beatlesfan36@hotmail.com
              </email>
              <email>
                lennonfan36@hotmail.com
              </email>
            </Client>
            <?xml version="1.0" encoding="windows-1252" ?>
            <Client>
              <Address>
                <street>
                  4209 El Camino Real
                </street>
                <city>
                  Mountain View
                </city>
                <state>
                  CA
                </state>
                <zip>
                  95033
                </zip>
              </Address>
              <phone>
                <home>
                  6503310091
                </home>
              </phone>
            </Client>

              如果您有興趣,還可以使用一般的 SQL 檢索 contactinfo 列中包含的完整 XML 文檔集。簡(jiǎn)單的 "select contactinfo from client" 語句就能夠完成這個(gè)任務(wù)。

              檢索特定的 XML 元素

              用戶常常希望檢索 XML 文檔中的特定元素。用 XQuery 完成這個(gè)任務(wù)很容易。假設(shè)希望檢索所有提供了傳真號(hào)的客戶的傳真號(hào)。下面是編寫這種查詢的一種方法:

            清單 14. 檢索客戶傳真號(hào)的 FLWOR 表達(dá)式
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
            return $y

              第一行指示 DB2 調(diào)用它的 XQuery 分析器。下一行指示 DB2 遍歷 CLIENTS.CONTACTINFO 列中包含的 Client 元素的 fax 子元素。每個(gè) fax 元素依次綁定到變量 $y。第三行指示對(duì)于每次迭代返回 $y 的值。結(jié)果是一系列 XML 元素,如下所示。

            清單 15. 前一個(gè)查詢的示例輸出
                      
            <fax>4087776666</fax>
            <fax>4085555555</fax>  

              (這里顯示的輸出經(jīng)過了簡(jiǎn)化。XML 版本信息已經(jīng)去掉了,因?yàn)樗鼘?duì)于本教程并不重要。但是,在 DB2 中運(yùn)行的 XQuery 都會(huì)返回這些信息。示例見 清單 13。)

              清單 14 所示的查詢也可以表示為一個(gè)三步的路徑表達(dá)式:

            清單 16. 檢索客戶傳真號(hào)的路徑表達(dá)式
                      
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax

              在 XQuery 基礎(chǔ) 一節(jié)中,了解了文本節(jié)點(diǎn)。我們?cè)谶@里應(yīng)用這一知識(shí)。假設(shè)不希望從查詢獲得 XML 片段,而是獲得 XML 元素值的文本表示。為此,可以在 return 子句中調(diào)用 text() 函數(shù):

            清單 17. 檢索客戶傳真號(hào)的文本表示的兩個(gè)查詢
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax
            return $y/text()
            (或)
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/fax/text()

              這些查詢的輸出是:

            清單 18. 前兩個(gè)查詢的示例輸出
                      
            4087776666
            4085555555

              本節(jié)中前面的查詢的結(jié)果相當(dāng)簡(jiǎn)單,因?yàn)樗鼈兌忌婕?fax 元素,這個(gè)元素基于一種原始數(shù)據(jù)類型。當(dāng)然,元素可能基于復(fù)雜的類型,可能包含子元素(或嵌套的層次結(jié)構(gòu))。客戶聯(lián)系信息的 Address 元素就是這種元素的例子。考慮以下 XQuery 會(huì)返回什么:

            清單 19. 檢索復(fù)雜 XML 類型的 XQuery
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
            return $y
            (或)
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address

              如果您猜測(cè)會(huì)返回一系列 XML 片段,其中包含 Address 元素及其所有子元素,那么您猜對(duì)了。下面是輸出的摘錄:

            清單 20. 前面查詢的部分輸出
                      
            <Address>
             <street>5401 Julio Ave.</street>
             <city>San Jose</city>
             <state>CA</state>
             <zip>95116</zip>
            </Address>
            <Address>
             <street>1204 Meridian Ave.</street>
             <apt>4A</apt>
             <city>San Jose</city>
             <state>CA</state>
             <zip>95124</zip>
            </Address>
            <Address>
              <street>9407 Los Gatos Blvd.</street>
              <city>Los Gatos</city>
              <state>CA</state>
              <zip>95032</zip>
            </Address>
              
            . . . 

              根據(jù) XML 元素值進(jìn)行過濾的查詢

              用戶常常希望在 XQuery 中指定基于 XML 的過濾條件。這也很容易。在本節(jié)中,您將看到如何讓前面的 XQuery 示例更有選擇性。

              指定單一過濾謂詞

              我們先研究一下如何返回郵政編碼為 95116 的所有客戶的郵政地址。可以將 where 子句結(jié)合進(jìn) XQuery,從而根據(jù) DB2 中存儲(chǔ)的示例 XML 文檔中的 zip 元素值對(duì)結(jié)果進(jìn)行過濾。將一個(gè) where 子句添加到 清單 19 中的 FLWOR 表達(dá)式中,從而只獲得感興趣的地址,如下所示:

            清單 21. 帶 “where” 子句的 FLWOR 表達(dá)式
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
            where $y/zip="95116"
            return $y

              添加的 where 子句相當(dāng)簡(jiǎn)單。for 子句依次將變量 $y 綁定到每個(gè)地址。這個(gè) where 子句包含一個(gè)簡(jiǎn)短的路徑表達(dá)式,它從每個(gè)地址導(dǎo)航到其中嵌套的 zip 元素。僅當(dāng)這個(gè) zip 元素的值等于 95116 時(shí),這個(gè) where 子句才為真(因此獲得這個(gè)地址)。

              因?yàn)橹挥幸粋€(gè)客戶的郵政編碼為 95116,返回的結(jié)果是:

            清單 22. 前一個(gè)查詢的輸出
                      
            <Address>
             <street>5401 Julio Ave.</street>
             <city>San Jose</city>
             <state>CA</state>
             <zip>95116</zip>
            </Address>

              可以通過在路徑表達(dá)式中添加謂詞來獲得同樣的結(jié)果,如下所示:

            清單 23. 帶過濾謂詞的路徑表達(dá)式
                      
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address[zip="95116"]

              指定多個(gè)過濾謂詞

              當(dāng)然,通過根據(jù)郵政編碼值進(jìn)行過濾,也可以返回與街道地址無關(guān)的元素。還可以在一個(gè)查詢中根據(jù)多個(gè) XML 元素值進(jìn)行過濾。下面的查詢返回那些住在 San Jose 市或者郵政編碼為 95032(這是加利福尼亞 Los Gatos 的郵政編碼)的客戶的電子郵件信息。

            清單 24. 用 FLWOR 表達(dá)式根據(jù)多個(gè) XML 元素值進(jìn)行過濾
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
            where $y/Address/zip="95032" or $y/Address/city="San Jose"
            return $y/email

              這個(gè)示例修改了 for 子句,從而將變量 $y 綁定到 Client 元素而不是 Address 元素。這樣就可以根據(jù)子樹的一部分(Address)對(duì) Client 元素進(jìn)行過濾,但是返回子樹的另一部分(email)。where 子句和 return 子句中的路徑表達(dá)式必須相對(duì)于綁定到變量(在這個(gè)示例中是 $y)的元素。

              同樣的查詢可以更精確地表示為路徑表達(dá)式:

            清單 25. 用路徑表達(dá)式根據(jù)多個(gè) XML 元素值進(jìn)行過濾
                      
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client[Address/zip="95032" 
            or Address/city="San Jose"]/email;

              對(duì)于 clients 表中的示例數(shù)據(jù),前面兩個(gè)查詢的輸出是:

            清單 26. 查詢輸出
                      
            <email>
              love2shop@yahoo.com
            </email>
            <email>
              beatlesfan36@hotmail.com
            </email>
            <email>
              lennonfan36@hotmail.com
            </email>

              XQuery 和 SQL 之間差異的實(shí)際示例

              如果觀察 清單 26 中的查詢輸出,您可能會(huì)發(fā)現(xiàn)返回的結(jié)果在兩個(gè)方面與 SQL 程序員的預(yù)期有顯著差異:

              對(duì)于沒有提供電子郵件地址的客戶,沒有返回 XML 數(shù)據(jù)。

              在我們的 示例數(shù)據(jù) 中,有四個(gè)客戶滿足查詢的選擇條件(住在 San Jose 或者郵政編碼為 95032),但是這一事實(shí)沒有反映在查詢結(jié)果中。為什么呢?因?yàn)槠渲袃蓚€(gè)客戶的記錄中沒有 email 元素。因?yàn)?XQuery 不使用空值,這些 “缺失的” 信息不會(huì)反映在結(jié)果中。

              輸出沒有表明哪些電子郵件地址來自同一個(gè) XML 文檔。

              仔細(xì)看 示例數(shù)據(jù),就會(huì)發(fā)現(xiàn) 清單 26 所示的最后兩個(gè)電子郵件地址包含在同一個(gè) XML 文檔中(也就是說,它們屬于同一個(gè)客戶)。這一點(diǎn)在輸出中看不出來。

              在某些情況下,這兩種表現(xiàn)可能正是我們需要的,但在其他情況下可能不理想。例如,如果希望向記錄的每個(gè)帳號(hào)發(fā)送一封電子郵件,那么會(huì)遍歷 XML 格式的客戶電子郵件地址列表,這在應(yīng)用程序中很容易辦到。但是,如果希望向每個(gè)客戶只發(fā)送一次通知,包括那些只提供了街道地址的客戶,那么前面的 XQuery 就不夠了。

              可以以多種方式改寫前面的查詢,讓返回的結(jié)果以某種方式表達(dá)出缺失的信息,并表明多個(gè)電子郵件地址來自同一個(gè)客戶記錄(即,同一個(gè) XML 文檔)。在本教程后面,您將學(xué)到如何編寫這樣的查詢。但是,如果只是希望返回的列表中對(duì)于每個(gè)客戶只包含一個(gè)電子郵件地址,那么只需稍稍修改前面的查詢:

            清單 27. 返回客戶的第一個(gè) email 元素
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
            where $y/Address/zip="95032" or $y/Address/city="San Jose"
            return $y/email[1]
            (或)
            xquery
            db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client[Address/zip="95032" 
            or Address/city="San Jose"]/email[1];

              這兩個(gè)查詢都指示 DB2 返回在符合條件的 XML 文檔(客戶聯(lián)系記錄)中找到的第一個(gè) email 元素。如果對(duì)于某個(gè)符合條件的客戶沒有找到電子郵件地址,那么它不返回這個(gè)客戶的任何信息。因此,這兩個(gè)查詢產(chǎn)生下面的輸出:

            清單 28. 查詢輸出
                      
            <email>
              love2shop@yahoo.com
            </email>
            <email>
              beatlesfan36@hotmail.com
            </email>

              XML 數(shù)據(jù)轉(zhuǎn)換

              XQuery 的一個(gè)強(qiáng)大功能是能夠?qū)?XML 數(shù)據(jù)從一種形式的 XML 轉(zhuǎn)換為另一種。在本節(jié)中,您將了解進(jìn)行 XML 數(shù)據(jù)轉(zhuǎn)換是多么容易。

              將 XML 轉(zhuǎn)換為 HTML

              在基于 Web 的應(yīng)用程序中,常常需要將全部或部分 XML 文檔轉(zhuǎn)換為 HTML 以便進(jìn)行顯示。利用 XQuery 很容易完成這個(gè)過程。請(qǐng)考慮以下查詢,它檢索客戶的地址、按郵政編碼對(duì)結(jié)果進(jìn)行排序并將輸出轉(zhuǎn)換為 XML 元素,這些元素是一個(gè)無序 HTML 列表的組成部分:

            清單 29. 查詢 DB2 XML 數(shù)據(jù)并返回 HTML 形式的結(jié)果
                      
            xquery
            <ul> {
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client/Address
            order by $y/zip
            return <li>{$y}</li>
            } </ul>

              這個(gè)查詢以 xquery 關(guān)鍵字開頭,從而向 DB2 分析器表示 XQuery 用作主要語言。第二行使無序列表的 HTML 標(biāo)記(<ul>)出現(xiàn)在結(jié)果中。它還引入一個(gè)花括號(hào),這是這個(gè)查詢中使用的兩對(duì)花括號(hào)中的第一對(duì)。花括號(hào)讓 DB2 計(jì)算并處理其中包含的表達(dá)式,而不是將它作為字符串對(duì)待。

              第三行遍歷客戶的地址,依次將變量 $y 綁定到每個(gè) Address 元素。第四行包含一個(gè) order by 子句,它指定結(jié)果必須根據(jù)客戶的郵政編碼(即綁定到 $y 的每個(gè) Address 的 zip 子元素)進(jìn)行升序排序(這是默認(rèn)次序)。return 子句表示將 Address 元素包圍在 HTML 列表項(xiàng)標(biāo)記中,然后再返回。最后一行結(jié)束查詢并完成 HTML 無序列表標(biāo)記。

              這個(gè)查詢的部分輸出如下:

            清單 30. 前一個(gè)查詢的 HTML 輸出
                      
            <ul>
             <li>
               <Address>
                 <street>9407 Los Gatos Blvd.</street>
                 <city>Los Gatos</city>
                 <state>CA</state>
                 <zip>95032</zip>
               </Address>
             </li>
             <li>
               <Address>
                 <street>4209 El Camino Real</street>
                 <city>Mountain View</city>
                 <state>CA</state>
                <zip>95033</zip>
               </Address>
             </li>
            . . .
            </ul>

              使用轉(zhuǎn)換表示 XML 文檔中缺失的或重復(fù)的元素

              我們來考慮前面提出的一個(gè)主題:如何編寫 XQuery 在返回的結(jié)果中表示缺失的值,以及表示一個(gè) XML 文檔(比如一個(gè)客戶記錄)包含重復(fù)的元素(比如多個(gè)電子郵件地址)。一種方法涉及到將返回的輸出包裝在一個(gè)新的 XML 元素中,如以下查詢所示:

            清單 31. 在 XQuery 結(jié)果中表示缺失的值或重復(fù)的元素
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
            where $y/Address[zip="95032"] or $y/Address[city="San Jose"]
            return <emailList> {$y/email} </emailList>

              運(yùn)行這個(gè)查詢會(huì)返回一系列 emailList 元素,每個(gè)符合條件的客戶記錄都有一個(gè) emailList 元素。每個(gè) emailList 元素將包含電子郵件數(shù)據(jù)。如果 DB2 在一個(gè)客戶的記錄中只找到一個(gè)電子郵件地址,那么它會(huì)返回這個(gè)元素及其值。如果找到多個(gè)電子郵件地址,就會(huì)返回所有 email 元素及其值。最后,如果沒有找到電子郵件地址,就會(huì)返回一個(gè)空的 emailList 元素。

              對(duì)于我們的示例數(shù)據(jù),這個(gè)查詢的輸出是:

            清單 32. 前一個(gè)查詢的輸出
                      
            <emailList>
              <email>love2shop@yahoo.com</email>
            </emailList>
            <emailList/>
            <emailList/>
            <emailList>
              <email>beatlesfan36@hotmail.com</email>
              <email>lennonfan36@hotmail.com<emailList>
            </emailList>   

              條件邏輯

              可以使用幾個(gè)簡(jiǎn)單的關(guān)鍵字將條件邏輯結(jié)合進(jìn) XQuery 中。

              假設(shè)您要聯(lián)絡(luò)每位客戶。您最希望通過電子郵件與他們?nèi)〉寐?lián)絡(luò),但如果沒有他們的電子郵件地址,那么就向他們家里打電話。如果也沒有家庭電話號(hào)碼,就通過郵局郵寄一封信。因此,需要查詢 DB2 clients 表,獲得一個(gè)包含每個(gè)客戶的單一電子郵件地址、家庭電話號(hào)碼或郵政地址的聯(lián)系列表。

              如果將條件邏輯結(jié)合進(jìn) XQuery 中,這個(gè)任務(wù)就很容易完成。獲得所需信息的一種方法如下:

            清單 33. 具有分三部分的條件表達(dá)式的 XQuery
                      
            xquery
            for $y in db2-fn:xmlcolumn('CLIENTS.CONTACTINFO')/Client
            return (
             if ($y/email) then $y/email[1]
             else if ($y/phone/home) then <homePhone>{$y/phone/home/text()}</homePhone>
             else $y/Address)

              我們來看看這個(gè)查詢的第四行到第六行。可以看到,它們是 return 子句的組成部分,因此決定查詢的輸出是什么。

              第四行檢查文檔中是否至少有一個(gè) email 元素;如果有,那么它指定應(yīng)該返回第一個(gè) email 元素。如果沒有 email 元素,那么執(zhí)行第五行。它指示 DB2 在 phone 元素下尋找 home 元素。如果文檔中包含家庭電話號(hào)碼,那么提取它的文本節(jié)點(diǎn)并作為新的 “homePhone” 元素的一部分返回。最后,如果客戶的聯(lián)系文件(XML 文檔)中沒有電子郵件地址和家庭電話號(hào)碼,那么 DB2 返回完整的 Address 元素。因?yàn)?clients 表 中的所有記錄都包含郵政地址,所以這個(gè)查詢的邏輯確保 DB2 會(huì)為每個(gè)客戶返回一種聯(lián)系方式。

              這個(gè)查詢的輸出是:

            清單 34. 查詢輸出
                      
            <email>
              love2shop@yahoo.com
            </email>
            <Address>
              <street>
                1204 Meridian Ave.
              </street>
              <apt>
                4A
              </apt>
              <city>
                San Jose
              </city>
              <state>
                CA
              </state>
              <zip>
                95124
              </zip>
            </Address>
            <homePhone>
              4083332222
            </homePhone>
            <email>
              golfer12@yahoo.com
            </email>
            <email>
              beatlesfan36@hotmail.com
            </email>
            <homePhone>
              6503310091
            </homePhone>

              “混合型” 查詢

              您已經(jīng)看到了如何編寫 XQuery 來檢索 XML 文檔片段、創(chuàng)建 XML 輸出的新形式以及根據(jù)在查詢本身指定的條件返回不同的輸出。這些都是查詢 DB2 中存儲(chǔ)的 XML 數(shù)據(jù)的簡(jiǎn)單方法。

              您要知道,關(guān)于 XQuery 要學(xué)習(xí)的內(nèi)容遠(yuǎn)比本教程討論的多得多。但是,有一個(gè)主題是我們不能忽略的:如何編寫同時(shí)包含 SQL 和 XQuery 表達(dá)式的查詢。如果需要讓查詢同時(shí)根據(jù) XML 和非 XML 列值進(jìn)行過濾,那么就需要掌握這種技術(shù)。

              因?yàn)楸窘坛讨饕P(guān)注 XQuery 并將它用作頂級(jí)語言,所以我們先研究如何將 SQL 嵌入 XQuery 中。但一定要注意,也可以采用相反的做法 —— 將 XQuery 嵌入 SQL 中。在本教程末尾,您會(huì)看到這種做法的一個(gè)簡(jiǎn)短示例。但是,關(guān)于 SQL/XML 以及如何將 XQuery 嵌入 SQL 中的更多信息,請(qǐng)參見 參考資料。

              將 SQL 嵌入 XQuery 中

              要將 SQL 嵌入 XQuery 中,需要使用 db2-fn:sqlquery 函數(shù)替代 db2-fn:xmlcolumn 函數(shù)。db2-fn:sqlquery 函數(shù)執(zhí)行一個(gè) SQL 查詢并只返回選擇的數(shù)據(jù)。傳遞給 db2-fn:sqlquery 的 SQL 查詢必須只返回 XML 數(shù)據(jù);這使 XQuery 能夠進(jìn)一步處理 SQL 查詢的結(jié)果。

              我們用一個(gè)示例將已經(jīng)討論的許多概念結(jié)合起來。假設(shè)希望獲得住在 San Jose 的 Gold 客戶的所有電子郵件地址。如果一個(gè)客戶有多個(gè)電子郵件地址,那么希望這些地址在輸出中是同一個(gè)記錄的組成部分。最后,如果符合條件的 Gold 客戶沒有提供電子郵件地址,那么希望檢索他的郵政地址。編寫這樣的查詢的一種方法如下:

            清單 35. 將 SQL 嵌入包含條件邏輯的 XQuery 中
                      
            xquery
            for $y in
            db2-fn:sqlquery('select contactinfo from clients where status=''Gold'' ')/Client
            where $y/Address/city="San Jose"
            return (
               if ($y/email) then <emailList>{$y/email}</emailList>
               else $y/Address 
            )

              我們仔細(xì)看看第三行,這里嵌入了一個(gè) SQL 語句。這個(gè) SELECT 語句包含一個(gè)基于 status 列的查詢謂詞,將這個(gè) VARCHAR 列的值與字符串 Gold 進(jìn)行比較。在 SQL 中,這樣的字符串要包圍在單引號(hào)中。盡管這個(gè)示例看起來似乎使用了雙引號(hào),但實(shí)際上是在比較值前后使用了兩個(gè)單引號(hào)(''Gold'')。“額外的” 單引號(hào)是轉(zhuǎn)義字符。如果在基于字符串的查詢謂詞外使用雙引號(hào)代替單引號(hào),就會(huì)出現(xiàn)語法錯(cuò)誤。

              這個(gè)查詢的輸出是:

            清單 36. 查詢輸出
                      
            <emailList>
              <email>
                love2shop@yahoo.com
              </email>
            <Address>
              <street>
                1204 Meridian Ave.
              </street>
              <apt>  4A
              </apt>
              <city>
                San Jose
              </city>
              <state>
                CA
              </state>
              <zip>
                95124
              </zip>
            </Address>

              將 XQuery 嵌入 SQL 中

              一定要注意,也可以將 XQuery 嵌入 SQL 中。實(shí)際上,DB2 9 提供了對(duì)標(biāo)準(zhǔn) SQL/XML 函數(shù)的支持,這些函數(shù)常常用來構(gòu)造以 SQL 為最外層(即頂級(jí))語言的混合型查詢。盡管詳細(xì)討論 DB2 的 SQL/XML 支持超出了本教程的范圍,但至少有兩個(gè)函數(shù)值得注意:

            XMLExists 允許導(dǎo)航到 XML 文檔中的一個(gè)元素(或其他類型的節(jié)點(diǎn))并對(duì)特定的條件進(jìn)行測(cè)試。在 SQL WHERE 子句中指定時(shí),XMLExists 將返回的結(jié)果限制為那些包含滿足指定條件(即指定的條件為 “true”)的 XML 文檔的行。您可能猜到了,應(yīng)該將 XQuery 表達(dá)式作為輸入傳遞給 XMLExists 函數(shù),從而導(dǎo)航到文檔中感興趣的節(jié)點(diǎn)。 XMLQuery 允許將 XML 放到 SQL/XML 查詢返回的 SQL 結(jié)果集中。它通常用來從 XML 文檔中檢索一個(gè)或多個(gè)元素。同樣,XMLQuery 函數(shù)也以 XQuery 表達(dá)式作為輸入。

              考慮以下查詢。這個(gè)查詢將 SQL 用作頂級(jí)語言并包含對(duì) XMLQuery 和 XMLExists 函數(shù)的調(diào)用:

            清單 37. 將 XQuery 路徑表達(dá)式嵌入 SQL 來獲取和限制 XML 數(shù)據(jù)
                      
            select name, status,
            xmlquery('$c/Client/phone/home' passing contactinfo as "c")
            from clients
            where xmlexists('$y/Client/Address[zip="95032"]' passing contactinfo as "y")

              這個(gè)查詢返回的結(jié)果集包括客戶姓名、狀態(tài)和家庭電話號(hào)碼列。前兩列包含 SQL VARCHAR 數(shù)據(jù),第三列包含從符合條件的 XML 文檔中提取的一個(gè) XML 元素。我們來仔細(xì)看看這個(gè)查詢的第二行和第四行。

              第二行在 SELECT 子句中調(diào)用 XMLQuery,這表示這個(gè)函數(shù)返回的結(jié)果應(yīng)該作為 SQL 結(jié)果集中的一列。我們指定一個(gè) XQuery 路徑表達(dá)式作為這個(gè)函數(shù)的輸入,這個(gè)表達(dá)式讓 DB2 導(dǎo)航到 Client 元素下面的 phone 元素的 home 子元素。這個(gè)路徑表達(dá)式引用一個(gè)變量($c),這個(gè)變量引用 contactinfo 列。

              第四行在 SQL WHERE 子句中調(diào)用 XMLExists,這表示 DB2 應(yīng)該根據(jù)一個(gè) XML 謂詞對(duì)結(jié)果進(jìn)行限制。這個(gè)謂詞是在路徑表達(dá)式中指定的,它表示我們只對(duì)具有特定郵政編碼的客戶感興趣。同樣,作為這個(gè) SQL/XML 函數(shù)的輸入提供的路徑表達(dá)式定義一個(gè)變量(在這個(gè)示例中是 $y),這個(gè)變量標(biāo)識(shí) DB2 將在哪里尋找 XML 文檔(在 contactinfo 列中)。

              對(duì)于 示例數(shù)據(jù),這個(gè)查詢的輸出是一個(gè)單行的結(jié)果集,其值如下:

            清單 38. 查詢輸出
                      
            Lisa Hansen     Silver  <home>4083332222</home>

              結(jié)束語

              本教程講解了 DB2 對(duì) XQuery 的支持,并解釋了幾個(gè)基本的語言概念。您學(xué)習(xí)了如何編寫和執(zhí)行針對(duì) DB2 中存儲(chǔ)的 XML 數(shù)據(jù)的簡(jiǎn)單 XQuery。

              本系列其他教程推薦

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 1 部分: DB2 規(guī)劃 1

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 1 部分: DB2 規(guī)劃 2

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 2 部分: 安全性

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 3 部分: 訪問 DB2 數(shù)據(jù)

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 4 部分: 處理 DB2 數(shù)據(jù)

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 5 部分: 處理 DB2 對(duì)象

              DB2 9 基礎(chǔ)(730 考試)認(rèn)證指南,第 6 部分: 數(shù)據(jù)并發(fā)性

             

            久久久久久久综合综合狠狠| 无码国产69精品久久久久网站| 狠狠色丁香久久婷婷综合五月| 国产精品久久久久久久久免费| 久久国产精品一区二区| 久久久久国产日韩精品网站| 伊人伊成久久人综合网777| 久久亚洲日韩精品一区二区三区| 久久丫精品国产亚洲av| 国产成人久久精品二区三区| 久久亚洲精品无码VA大香大香| 99久久99这里只有免费的精品| 久久男人中文字幕资源站| 久久不见久久见免费视频7| 久久一本综合| 久久成人影院精品777| 97精品依人久久久大香线蕉97| 九九久久精品无码专区| 国产激情久久久久久熟女老人 | 久久综合久久久| 久久国产精品无| 狠狠色丁香婷婷综合久久来来去 | 色天使久久综合网天天| 久久香蕉国产线看观看99| 久久久亚洲裙底偷窥综合| 久久艹国产| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 久久综合久久综合久久综合| 亚洲精品午夜国产VA久久成人| 久久影视综合亚洲| 久久有码中文字幕| 激情综合色综合久久综合| 99国内精品久久久久久久| 国产精品久久波多野结衣| 久久久久无码精品国产不卡| 99精品国产99久久久久久97| 无码国内精品久久综合88| 亚洲午夜福利精品久久| 亚洲国产精品成人久久蜜臀| 日本久久久久久久久久| 久久精品日日躁夜夜躁欧美|