程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介

DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介

編輯:DB2教程

開始之前

關於本系列

本系列教程為您講解 SQL 的一些基礎和高級話題以及 XQuery 的基礎知識,並展示如何使用 SQL 查詢或 XQuery 語句將常被問起的業務問題表達為數據庫查詢。開發人員和數據庫管理員可以使用本教程來提高他們的數據庫查詢技能。Academic Initiative 成員可以使用本教程系列作為他們數據庫課程的一部分。

本文中的所有例子都是基於 Aroma,這是一個示例數據庫,其中包含了在美國各地的商店中出售的咖啡和茶用品的銷售數據。每個例子由以下三部分組成:

以日常用語表達的一個業務問題

以 SQL 或 XQuery 表達的一個或多個例子查詢

顯示從數據庫返回的結果的一個表

本指南是為了讓讀者學習 SQL 語言和 XQuery 而設計的。和學習任何其他技能一樣,重要的是一邊學習一邊實踐。本指南給出的表定義和數據為學習提供了便利。

對於使用本指南作為學校課程一部分的學生而言,他們應該向老師學習連接到 Aroma 數據庫的操作,並了解本指南的設置與您本地設置的不同之處。

本教程是針對 DB2 Express-C 9 for Linux®, UNIX®, and Windows® (曾用名 Viper)編寫的。

關於本教程

本教程向讀者介紹 pureXML 和 XQuery。在 Aroma 數據庫中,惟一用到 XML 的地方就是 Comments 列。本系列的 第 1 部分中提到過這一列,這正是本教程,即本系列的第 7 部分的重點所在。

本教程首先對 XML 數據類型的特征和優點做一個基本的概述,然後將它與標准關系表進行比較。隨後,要求用戶編寫檢索 XML 元素的 XQuery 查詢,根據 XML 值過濾數據,轉換 XML 輸出,並使用各種子句更精確地選擇數據。本教程的最後一節介紹如何混合使用 XQuery 與 SQL,將這兩種語言的威力組合起來。

連接到數據庫

在使用 SQL 查詢或操縱數據之前,需要連接到一個數據庫。CONNECT 語句將一個數據庫連接與一個用戶名相關聯。

如果您使用本指南作為學校課程的一部分,那麼可以向老師詢問要連接到的數據庫的名稱。對於本系列,數據庫名為 aromadb。

要連接到 aromadb 數據庫,可以在 DB2 命令行處理器中輸入以下命令:

 CONNECT TO aromadb USER userid USING passWord

注意用老師告訴您的用戶 ID 和密碼替換 "userid" 和 "passWord"。如果不需要用戶 ID 和密碼,那麼只需使用以下命令:

 CONNECT TO aromadb

如果看到下面的消息,則說明您已經建立一個成功的連接:

 Database Connection Information 
 Database server   = DB2/NT 9.0.0 
 SQL authorization ID = USERID 
 Local database alias = AROMADB

建立連接後,就可以開始使用數據庫了。

關於 XML

什麼是 XML?

XML:

是不同的系統、平台、應用程序和組織之間交換數據的標准。

獨立於供應商和平台。

高度靈活。

適用於結構化、非結構化和半結構化數據的任意組合。

易於擴展 —— 可以隨需定義新的標記。

容易轉換為 “不同外觀” 的 XML,甚至可以轉換成其他格式,例如 Html。

容易檢查是否遵從某種模式。

通過大量可用的工具和標准,例如 XML 解析器、XSLT 和 XML 模式,以上幾點都已成為可能。它們大大減輕了應用程序處理專用數據格式的負擔。在消息格式、業務形式和服務頻繁變化的時代,XML 減少了為此需要對應用程序邏輯作出相應維護的成本和時間。

除了將 XML 用於數據交換以外,企業還以 XML 格式永久保存大量業務關鍵數據。原因很多,主要包括:

出於審計和法規順從性的目的,有些業務必須以原始格式保留 XML 文檔,
例如法律和財政文檔,在政府部門這一點尤為突出。

與關系模式相比,XML 是更適合的數據模型。不但對於面向內容的應用程序是這樣,對於某些面向數據的應用程序也是如此,
例如,在生命科學應用中,數據高度復雜,且具有分層的性質,可能包含相當多非結構化信息。目前,大多數基因組數據仍然以專用的平面文件格式存放,但是大家正在努力將其轉移到 XML 格式。

關系數據庫已經在提供對 XML 數據的存儲、處理、搜索和檢索功能。這通常是基於將 XML 文檔存儲到 LOB 中,或者將 XML 映射和分解成關系模式。

這些解決方案在功能上和性能上都有其固有的局限性。通常,基於 LOB 的存儲便於較快地插入和檢索整個文檔,但是由於在查詢執行時需要進行 XML 解析,在搜索和提取信息方面的性能不佳。如果在插入時建立索引,一定程度上可以提高這方面的性能。這樣做雖然可以加快查找符合搜索條件文檔的查詢的速度,但是會增加 XML 解析方面的開銷。而且,文檔片段的提取和子文檔級的更新仍然需要代價不菲的 XML 解析。

在本教程系列之前的幾個部分中,您已經閱讀了關於 SQL 的一些介紹,包括 SELECT 語句和數據定義語言(Data Definition Language,DDL)。XML 是另一種不同的組織數據和查詢數據的方式,它使用 XQuery 或 Xpath 來查詢數據。

在表格式中,關系數據被表示為行和列上的數據。XML 數據則將標記和數據放在一起。

示例數據

 <Comments> 
   <comment> 
     <comment_ID>5301</comment_ID> 
     <customer_info> 
       <fname>Scott</fname> 
       <lname>Phillips</lname> 
       <email>[email protected]</email> 
     </customer_info> 
     <feedback> 
       <type>opinion</type> 
       <content>Gold Tips was highly enjoyable!</content> 
     </feedback> 
     <store_rating> 
       <score>5</score> 
       <out_of>5</out_of> 
     </store_rating> 
     <store_response> 
       <required>no</required> 
     </store_response> 
   </comment> 
   <comment> 
     <comment_ID>5302</comment_ID> 
     <customer_info> 
       <fname>Barbara</fname> 
       <lname>Adams</lname> 
       <phone>6138617611</phone> 
     </customer_info> 
     <feedback> 
       <type>question</type> 
       <content>What are the top teas brands?</content> 
     </feedback> 
     <store_rating> 
       <score>4</score> 
       <out_of>5</out_of> 
     </store_rating> 
     <store_response> 
       <required>yes</required> 
       <completed>yes</completed> 
       <action>Please see our "All About Tea" page at www.aroma.com/tea</action> 
|-------10--------20--------30--------40--------50--------60--------70--------80--------9| 
|-------- XML error: The previous line is longer than the max of 90 characters ---------| 
     </store_response> 
   </comment> 
 </Comments>

單憑以上示例數據,是否能確定 Scott Phillips 的電子郵箱地址?其實只需順著嵌套標記創建的層次就能找到。由於 XML 將標記和數據存儲在一起,因此數據是自描述的,容易理解。

DB2 9

DB2 9 是業界第一款能同時管理關系結構和 pureXML 結構的數據的混合型數據服務器。長期以來,DB2 一直提供高性能的數據存儲和基於 SQL 標准的對關系數據的訪問方式,同時提供的還有諸如數據分區和高級索引之類的數據存儲優化和查詢優化技術。現在,DB2 在它已有的關系引擎的基礎上,更是引入了一種用於 XML 數據的優化的數據存儲引擎。

應用程序開發人員如今可以將 XML 數據直接存儲在 DB2 服務器中,並立即獲得事務處理、高級數據彈性(resilIEncy)、安全訪問等方面的優點,當然還有使用 XQuery 搜索大量 XML 數據的能力。

XML 數據與關系數據的比較

XML 有三大基本特性使之區別於關系模型:

XML 是自描述的。文檔不僅包含數據,還包含必要的元數據。因此,不需要模式的靜態定義,便可以搜索或更新 XML 文檔。而關系模型則需要更多的靜態模式定義。一個表中的所有行都必須有相同的模式。

XML 是分層的。文檔不僅表示基本信息,還以分層的形式表示關於數據項之間關系的信息。而在關系模型中,所有關系信息都需要通過主鍵或外鍵關系來表達,或者在其他關系中表示。

XML 是面向序列的(排序很重要)。關系模型則是面向集合的;排序並不重要。

以上三點中,任何一點都不能表明 XML 比純關系模型好或者壞。實際上,XML 和關系模型是互補的解決方案。有些數據具有分層的性質,有些數據具有標量的性質;有些數據有更嚴格的模式,而有些數據的模式不是那麼嚴格;有些數據需要符合特定的順序,有些數據則不需要。

何時使用 XML

在以下情況下,使用 XML 表示法較好:

模式是易變的。
如果數據的模式經常變化,考慮到變更關系模式的代價和難度,使用關系的形式表示這種數據不劃算。而 XML 的自描述性可以使得模式的修改更為簡單。

數據具有分層的性質。
有些數據具有標量的性質,對於這種數據,關系模型最為適合。但是還有一些數據具有分層的性質,而 XML 通常最適合表示這種數據。

數據表示業務對象,且一旦離開業務對象的上下文,其各個組成部分就失去意義。
例如,考慮一種典型的雇員和電話號碼之間的關系,其中一個雇員可以有多個電話號碼:一個是辦公室電話號碼,一個是傳真號碼,一個是家裡電話號碼,還有一個是手機號碼。如果最常見的用法是根據雇員檢索電話號碼,那麼,將數據標准化,引入一個表來跟蹤與一名雇員相關聯的多個電話號碼,這種做法不是很合理。更好的選擇是將電話號碼放在雇員關系中,使用 XML 表示它們。

應用程序具有稀疏屬性。
有些應用程序有很多可能出現的屬性,但是對於任意給定的數據值,其中大部分屬性都是缺少的。一個典型的例子就是商品編目。用於跟蹤給定商品的不同屬性的數目繁多,包括大小、顏色、織物、電源要求等等。但是,對於任何給定的對象,只有一部分屬性是相關的;我們可以說一件毛衣的織物是什麼,但是提起割草機的織物就荒謬之極。使用關系表來描述對象的特征成本很高,而且過於復雜。而將描述性的屬性表示為 XML 數據則是更自然的表示法,而且可以減少復雜性和搜索成本。

少量數據是高度結構化的。
在很多應用程序中,結構化信息對於應用程序至關重要,但是其數量很少。雖然可以用常規的關系來表示那樣的信息,但是這種方法會導致大量關系模式。相反,使用一個 XML 列,再輔以多種視圖,可以大大減少數據庫中受管理的對象的數量,從而減少維護成本。

創建支持 XML 的數據庫

在本系列的 第 1 部分中,介紹了用一個批處理文件創建 Aroma 數據庫。您可能想在將來創建自己的數據庫,所以本節將教您如何創建支持 XML 特性的數據庫。

用 Control Center 創建數據庫

在 DB2 Control Center 中,在左側菜單中右鍵單擊 All Databases 文件夾。選擇 Create Databse -> Standard。這時將彈出 Create Database Wizard。填入數據庫的名稱,然後選擇 Enable database for XML。


XML 編碼集
DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介

連續兩次單擊 Next,進入 Region 屏幕。將 Country/Region 值設為適當的值,將 Code set 設為 UTF-8。單擊 Finish 完成數據庫的創建。

用 Command Line Processor 創建數據庫

要用 DB2 CLP 創建相同的數據庫,可輸入以下代碼:

db2 create db aromadb using codeset utf-8 territory us

注意指定 UTF-8 作為數據庫的編碼集。XML 特性只能用於以編碼集 UTF-8 定義的只有一個數據庫分區的數據庫。將來您在創建自己的數據庫時別忘了包括這個參數。

關於 comments 列

在 Aroma 數據庫中,Sales 表有一個 Comments 列。

這個列由以下信息組成:

評論 ID

客戶信息:姓名、聯系方式(電話號碼和/或電子郵箱地址)

商店的響應(如果有的話)

客戶反饋:可以是意見、建議或疑問

最高為 5 分的商店評分

示例數據

<Comments> 
  <comment> 
    <comment_ID>5301</comment_ID> 
    <customer_info> 
      <fname>Scott</fname> 
      <lname>Phillips</lname> 
      <email>[email protected]</email> 
    </customer_info> 
    <feedback> 
      <type>opinion</type> 
      <content>Gold Tips was highly enjoyable!</content> 
    </feedback> 
    <store_rating> 
      <score>5</score> 
      <out_of>5</out_of> 
    </store_rating> 
    <store_response> 
      <required>no</required> 
    </store_response> 
  </comment> 
  <comment> 
    <comment_ID>5302</comment_ID> 
    <customer_info> 
      <fname>Barbara</fname> 
      <lname>Adams</lname> 
      <phone>6138617611</phone> 
    </customer_info> 
    <feedback> 
      <type>question</type> 
      <content>What are the top teas brands?</content> 
    </feedback> 
    <store_rating> 
      <score>4</score> 
      <out_of>5</out_of> 
    </store_rating> 
    <store_response> 
      <required>yes</required> 
      <completed>yes</completed> 
      <action>Please see our "All About Tea" page at www.aroma.com/tea</action> 
    </store_response> 
  </comment> 
</Comments>

為什麼用 XML?

前面幾個小節已經討論過 XML 的優點,但是在這個例子中,為什麼選擇 XML 列,而不是關系表列呢?

靈活性:
- 商店希望得到客戶的不同信息。
- 隨著時間的推移,商店可能改進其獲取反饋的方法,從而導致不同類型的數據出現。
- 例如,促銷調查不同於常規的銷售調查。這種變化用 XML 比較容易存儲,但是用關系列就不行。

敏捷性:
- 表結構不需要隨數據變化。

自描述性:
- 商店經理/雇員可以直接理解 XML 形式的客戶評論,而不需要額外的解釋。

層次性:
- 數據具有分層的性質。
- 如果離開評論的上下文,客戶信息就變得沒有意義。

問題示例

Aroma 數據庫中存儲了哪些評論?

紐約的商店收到了哪些評論?

哪些評論需要商店作出響應?哪些評論還沒有處理完?

以 Html 列表的形式顯示所有未處理完的評論。

顯示所有評論,並按照三種類別(評論、建議和疑問)對它們進行分組。

計算和顯示每種類型的評論的數量。

計算和顯示所有評論給出的平均評分。

使用中的注意事項

在 Sales 數據庫中,comments 列只有從 2006 年 3 月開始的那些行的值。

關於 XQuery

在之前的例子中,都是使用 SQL SELECT 語句提取數據。涉及 XML 數據的查詢可以用 XML 自己的查詢語言,即 XQuery 來完成。

XQuery 在一些關鍵方面與 SQL 有所不同,主要是因為這兩種語言是為具有不同特征的不同數據模型而設計的。XML 文檔包含層次,並且有固有的順序。而基於 SQL 的 DBMS 所支持的標量數據結構是平面的,又是基於集合的。行之間沒有順序。

這兩種數據模型之間的差異,導致它們相應的查詢語言在很多基本方面存在差異。下面的表列出了一些差異。

XQuery SQL 支持路徑表達式,使程序員可以在 XML 的層次結構中導航 不支持路徑表達式 支持有類型的和無類型的數據 總是用特定類型進行定義 不存在 null 值,因為 XML 文檔忽略沒有的或未知的數據 使用 null 值表示沒有的或未知的數據值 返回 XML 數據序列 返回不同 SQL 數據類型的結果集

兩種類型的 XQuery 表達式

本教程主要討論兩種重要類型的 XQuery 表達式:“FLWOR” 表達式和路徑表達式。

FLWOR 表達式很像 SQL 中的 SELECT-FROM-WHERE 表達式 —— 它用於在一組項目中進行迭代,可選地返回從每個項目計算到的值。而路徑表達式則是在 XML 元素的層次結構中進行導航,並返回路徑末端找到的元素。

和 SQL 中的 SELECT-FROM-WHERE 表達式一樣,XQuery FLWOR 表達式可能包含一些以某個關鍵詞開頭的子句。下面的關鍵詞用於開始 FLWOR 表達式中的一個子句:

  1. for 迭代一個輸入序列,將一個變量依次綁定到每個輸入項 2. let 聲明一個變量並為之賦值,可能是包含多個項的一個列表 3. where 指定用於過濾查詢結果的標准 4. order by 指定結果的排序順序 5. return 定義要返回的結果

XQuery 中的路徑表達式由一系列的“步”組成,之間以斜槓相隔。簡言之,每一步在 XML 層次中往裡導航一層,以發現前一步返回的元素的子元素。路徑表達式中的每一步可能還包含一個謂詞,用於過濾那一步返回的元素,只保留滿足某種條件的元素。

例如,對於前一小節給出的示例數據,假設變量 $comments 被綁定到一系列包含 <comment> 元素的文檔,那麼四步路徑表達式 $comments/comment/feedback[type = "suggestion"]/content 將返回屬於類型 "suggestion" 的評論的內容的列表。

在很多情況下,可以使用 FLWOR 表達式或路徑表達式編寫查詢。

檢索 XML 元素

問題

Aroma 數據庫中存儲了哪些客戶評論?

例子 FLWOR 查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS') 
return $y

例子路徑查詢

          xquery 
db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')


兩個查詢,一個結果

<Comments> 
  <comment> 
    <comment_ID>1</comment_ID> 
    <customer_info> 
      <fname>Christopher</fname> 
      <lname>Davis</lname> 
      <phone>4147301265</phone> 
      <email>[email protected]</email> 
    </customer_info> 
    <feedback> 
      <type>opinion</type> 
      <content>The employee named Heather Gray was very helpful.</content> 
    </feedback> 
    <store_rating> 
      <score>5</score> 
      <out_of>5</out_of> 
    </store_rating> 
    <store_response> 
      <required>no</required> 
    </store_response> 
  </comment> 
</Comments> 
 
<Comments> 
  <comment> 
    <comment_ID>101</comment_ID> 
    <customer_info> 
      <fname>Cynthia</fname> 
      <lname>Thomas</lname> 
      <email>[email protected]</email> 
    </customer_info> 
    <feedback> 
      <type>question</type> 
      <content>What countrIEs are major tea consumers?</content> 
    </feedback> 
    <store_rating> 
      <score>4</score> 
      <out_of>5</out_of> 
    </store_rating> 
    <store_response> 
      <required>yes</required> 
      <completed>yes</completed> 
      <action>Please see our "All About Tea" page at www.aroma.com/tea</action> 
    </store_response> 
  </comment> 
</Comments> 
 
 ...

注意:為了便於閱讀,結果在格式上有所調整。實際上,DB2 Command Editor 每行顯示一條評論。

DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介 提示:為了為 Command Editor 釋放內存,在結果區域單擊右鍵,然後選擇 Clear Results。

關於這兩個查詢

為了在 DB2 9 中直接執行 XQuery 查詢,必須在查詢的開頭加上關鍵詞 xquery。這個關鍵詞指示 DB2 調用它的 XQuery 解析器來處理請求。

注意:只有在使用 XQuery 作為最外層(頂層)語言時,才需要這麼做。如果是將 XQuery 表達式嵌入到 SQL 中,那麼不需要在表達式的前面加上 xquery 關鍵詞。

當使用 XQuery 作為頂層語言時,XQuery 需要一個輸入數據的來源。XQuery 獲得輸入數據的一種方法是調用一個名為 db2-fn:XMLcolumn 的數據源,調用該函數時帶一個參數,標識一個 DB2 表的表名和其中一個列的列名。

db2-fn:xmlcolumn 函數返回存儲在給定列中的一系列的 XML 文檔。這兩個例子查詢返回一系列的包含客戶評論信息的 XML 文檔。

注意,列名 Comments 和表名 aroma.sales 都是以大寫形式指定的。這是因為它們在被寫入到 DB2 的內部編目之前,通常會被轉換成大寫形式。因為 XQuery 是大小寫敏感的,小寫的表名和列名與 DB2 編目中大寫的名稱不能匹配。

檢索特定的 XML 元素

問題

Aroma 數據庫中存儲了哪些客戶評論?只顯示評論的內容。

例子 FLWOR 查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback/content 
return $y

例子路徑查詢

          xquery 
db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback/content

兩個查詢,一個結果

<content>The employee named Heather Gray was very helpful.</content> 
<content>What countrIEs are major teas consumers?</content> 
<content>Demitasse Ms was highly enjoyable!</content> 
<content>Xalapa Lapa was great!</content> 
<content>Aroma should consider selling Jamaican Butter Rum.</content> 
<content>Darjeeling Special was not enjoyable at all.</content> 
<content>Special Tips is my favorite.</content> 
...

關於這兩個查詢

這兩個查詢雖然產生相同的結果,但是它們的執行過程稍微有些不同。

在 FLWOR 查詢中,第二行指示 DB2 迭代 aroma.sales.comments 列中包含的 <Comments> 元素的 content 子元素。每個 content 元素依次被綁定到變量 $y。第三行表明,對於每次迭代,返回 $y 的值。結果是一系列的 XML 元素。

在路徑查詢中,第一步調用 db2-fn:xmlcolumn 函數獲得 aroma.sales 表的 Comments 列中包含的 XML 文檔的一個列表。第二步返回所有這些文檔中的 <Comments> 元素,第三步返回嵌套在這些 <Comments> 元素中的 <comment> 元素,第四步返回嵌套在 <comment> 元素中的 <feedback> 元素,第五步返回嵌套在 <feedback> 元素中的 <content> 元素。

text() 函數

問題

Aroma 數據庫中存儲了哪些客戶評論?將評論的內容顯示為文本。

例子 FLWOR 查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback/content 
return $y/text()

例子路徑查詢

          xquery 
db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback/content/text()

兩個查詢,一個結果

The employee named Heather Gray was very helpful. 
What countrIEs are major teas consumers? 
Demitasse Ms was highly enjoyable! 
Xalapa Lapa was great! 
Aroma should consider selling Jamaican Butter Rum. 
Darjeeling Special was not enjoyable at all. 
Special Tips is my favorite. 
...

關於這兩個查詢

這兩個查詢調用 text() 函數返回 XML 元素值的文本表示。

根據 XML 元素值進行過濾

問題

Aroma 數據庫中存儲了哪些客戶建議?將它們顯示為文本。

例子 FLWOR 查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback 
where $y/type = "suggestion" 
return $y/content/text()

例子路徑查詢

          xquery 
db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback[type = 
"suggestion"]/content/text()

兩個查詢,一個結果

Aroma should consider selling Jamaican Butter Rum. 
Aroma should consider selling Gyokuro Asahi Pearl Dew. 
Aroma should consider selling Orange Pekoe. 
Aroma should consider selling Vanilla Creme. 
Aroma should consider selling China Yunnan. 
Aroma should consider selling Kona Fancy 100%. 
Aroma should consider selling Blackcurrant. 
Aroma should consider selling Sencha. 
...

關於這兩個查詢

XQuery 的 where 子句類似於 SQL 的 WHERE 子句。在 FLWOR 查詢中,它根據 XML 文檔的 type 元素的值對結果進行過濾。

for 子句將變量 $y 依次綁定到每個反饋。where 子句包含一個小型的路徑表達式,這個路徑表達式從每個 feedback 元素導航到嵌套在它裡面的 type 元素。只有當這個 type 元素的值等於 "suggestion" 時,where 子句才為 true(返回內容)。

附加的謂詞 [type = "suggestion"] 用於創建相應的路徑查詢。

問題

Aroma 數據庫中存儲了哪些客戶建議和疑問?將它們顯示為文本。

例子 FLWOR 查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback 
where $y/type = "suggestion" or $y/type = "question" 
return $y/content/text()

例子路徑查詢

          xquery 
db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback[type = 
"suggestion" 
or type = "question"]/content/text()

兩個查詢,一個結果

What countrIEs are major tea consumers? 
Aroma should consider selling Jamaican Butter Rum. 
Aroma should consider selling Gyokuro Asahi Pearl Dew. 
Who do you buy your tea from? 
What is the maximum amount of coffee one person can safely consume per day? 
Aroma should consider selling Orange Pekoe. 
Aroma should consider selling Vanilla Creme. 
...

關於這兩個查詢

和 SQL 一樣,可以使用搜索條件來細化 XML 元素的選擇。本系列的第 3 部分,使用 AND、NOT 和 OR 連接詞創建復雜條件 對搜索條件和邏輯操作符作了詳細的討論。

轉換 XML 輸出

問題

哪些商店響應尚未完成?以 Html 列表顯示動作文本。

例子查詢

          xquery 
<ul> { 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/store_response 
where $y/completed = "no" 
return <li>{$y/action/text()}</li> 
} </ul>

結果

<ul> 
<li>Thank you for your Excellent suggestion! Aroma Coffee and Tea Company is actually 
planning on ordering the product you've suggested--check our stores next month!</li> 
<li>Please see our "All About Tea" page at www.aroma.com/tea</li> 
<li>The Aroma Coffee and Tea Company supports local growers in North America as well 
as imports. Our mission is to offer the best-quality coffee and tea products from North 
America as well as around the world. All of our supplIErs must meet all of our quality 
control standards.</li> 
<li>Thank you for your Excellent suggestion! Currently, Aroma Coffee and Tea Company 
does not plan to include the product you've suggested in our purchase plans. We will 
keep your suggestion on file and we will consider it in the future.</li> 
<li>Thank you for your Excellent suggestion--we completely agree! Please visit 
www.aroma.com.</li> 
<li>Please see our "All About Coffee" page at www.aroma.com/coffee</li> 
<li>Please see our "All About Tea" page at www.aroma.com/tea</li> 
... 
</ul>

注意: 為便於閱讀,結果在格式上做了調整。DB2 Command Editor 實際上用一行顯示整個列表。

關於該查詢

XQuery 的一個強大之處是可以將 XML 輸出從一種形式的 XML 轉換成另一種形式。例如,可以使用 XQuery 檢索存儲的整個 XML 文檔或它的一部分,然後將輸出轉換成 HTML,以便在 Web 浏覽器中顯示。例子查詢檢索商店響應,將其轉換成 XML 元素,作為無序 Html 列表的一部分。

查詢的第二行將無序列表的 Html 標記(<ul>)包括在結果中。它還引入了一個花括號,這是本查詢中使用的兩組花括號中的第一個花括號。花括號指示 DB2 計算和處理被括在其中的表達式,而不是將其當作文字字符串。

第三行迭代商店響應,將變量 $y 依次綁定到每個 store_response 元素。return 子句表明,在返回 store_response 元素之前,將其用 HTML 列表標記包圍起來。最後一行結束查詢,並完成 Html 無序列表標記。

if-then-else 表達式

問題

哪些商店響應尚未處理完? 將評論 ID、客戶信息和商店動作顯示為 <suggestion> 和 <question> 元素下對應的 XML 元素。

例子查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment 
where $y/store_response/completed = "no" 
return 
 ( 
  if ($y/feedback/type = 'suggestion') 
    then 
      <suggestion> 
      {$y/comment_ID, 
       $y/customer_info, 
       $y/store_response/action} 
      </suggestion> 
    else 
      <question> 
      {$y/comment_ID, 
       $y/customer_info, 
       $y/store_response/action} 
      </question> 
)


結果

<suggestion> 
  <comment_ID>4201</comment_ID> 
  <customer_info> 
    <fname>Karen</fname> 
    <lname>Richardson</lname> 
    <phone>3546388558</phone> 
    <email>[email protected]</email> 
  </customer_info> 
  <action>Thank you for your Excellent suggestion! Aroma Coffee and Tea Company 
    is actually planning on ordering the product you've suggested--check our stores 
    next month!</action> 
</suggestion> 
 
<question> 
  <comment_ID>9601</comment_ID> 
  <customer_info> 
    <fname>Thomas</fname> 
    <lname>Nelson</lname> 
    <phone>0055238541</phone> 
  </customer_info> 
  <action>Please see our "All About Tea" page at www.aroma.com/tea</action> 
</question> 
 
<question> 
  <comment_ID>15503</comment_ID> 
  <customer_info> 
    <fname>Joseph</fname> 
    <lname>Sanders</lname> 
    <phone>6717072487</phone> 
    <email>[email protected]</email> 
  </customer_info> 
  <action>The Aroma Coffee and Tea Company supports local growers in North 
  America as well as imports. Our mission is to offer the best-quality coffee 
  and tea products from North America as well as around the world. All of our 
  supplIErs must meet all of our quality-control standards.</action> 
</question> 
 
...

注意:為便於閱讀,結果在格式上做了調整。實際上,DB2 Command Editor 每行顯示一條結果。

關於該查詢

可以將 XQuery 轉換 XML 輸出的能力與它內置的對條件邏輯的支持相結合,減少應用程序代碼的復雜性。查詢創建復雜的 XML 元素,位於 <suggestion> 和 <question> 元素下,其中包含關於評論 ID、客戶信息和商店動作的信息。

這個結果對於執行商店響應的人來說很有用,他已經有了足夠的信息來做他的工作。

DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介 要點: <comment_ID> 元素必須嚴格按照大小寫拼寫,因為 XQuery 是大小寫敏感的。

Order By 子句

問題

Aroma 數據庫中存儲了哪些客戶意見?按照商店評分從低到高排列。

例子查詢

          xquery 
for $y in db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment 
where $y/feedback/type = "opinion" 
order by $y/store_rating/score 
return 
  <comment> 
    <rating>{$y/store_rating/score/text()}</rating> 
    <opinion>{$y/feedback/content/text()}</opinion> 
  </comment>

結果

<comment> 
  <rating>2</rating> 
  <opinion>Darjeeling Special was not enjoyable at all.</opinion> 
</comment> 
 
... 
 
<comment> 
  <rating>3</rating> 
  <opinion>Good store, but quality of customer service could be better.</opinion> 
</comment> 
 
... 
 
<comment> 
  <rating>4</rating> 
  <opinion>The employee named Heather Gray was very helpful.</opinion> 
</comment> 
 
...

注意: 為便於閱讀,結果在格式上做了調整。實際上,DB2 Command Editor 每行顯示一條結果。

關於該查詢

order by 子句規定返回的結果必須按照商店評分以升序(默認順序)排序。

Let 子句

問題

Comments 列中存儲了多少條客戶意見?多少條建議?多少個疑問?

例子查詢

          xquery 
for $t in distinct-values 
(db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/feedback/type) 
let $tc := db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment[feedback/type = $t] 
return 
  <comments> 
    <type>{$t}</type> 
    <count>{count($tc)}</count> 
  </comments>

結果

<comments> 
  <type>opinion</type> 
  <count>1220</count> 
</comments> 
<comments> 
  <type>question</type> 
  <count>364</count> 
</comments> 
<comments> 
  <type>suggestion</type> 
  <count>251</count> 
</comments>

注意:為便於閱讀,結果在格式上做了調整。實際上,DB2 Command Editor 每行顯示一條結果。

關於該查詢

該查詢計算每種類型有多少條評論。

let 子句用於將一個值(可能是由多個項目組成的一個列表)賦給一個變量, FLWOR 表達式的其他子句中可以使用這個變量。

for 子句中的 distinct-values 函數返回 Comments 列中的 <comments> 元素中的 type 元素出現的所有不同值的列表。有三種不同的 type 值:opinion、suggestion 和 question。for 子句將變量 $t 依次綁定到每種 type 值。對於 $t 的每個值,let 子句再次掃描 Comments 列,將變量 $tc 綁定到類型與 $t 中的 type 匹配的所有評論的一個列表。return 子句為每種不同的 type 值構造一個新的 <comments> 元素。每個 <comments> 元素包含兩個子元素:一個是包含類型值的 <type> 元素,還有一個是包含指定類型的評論的數量的 <count> 元素。

count 函數是 XQuery 提供的大量內置函數中的一個。下一節會給出關於內置函數的更多例子。

內置函數

問題

所有評論中對商店的平均評分是多少?

例子查詢

          xquery 
avg(db2-fn:XMLcolumn('AROMA.SALES.COMMENTS')/Comments/comment/store_rating/score)

結果

4.11389645776567

關於該查詢

db2-fn:XMLcolumn 函數返回存儲在 Comments 列中的所有評分的一個序列,avg 函數計算它們的平均值。

下面的表闡釋了業務查詢中常用的一些 XQuery 函數:

函數 描述 sum(sequence-expression) 計算序列中所有值的總和 avg(sequence-expression) 計算序列中所有值的平均值 max(sequence-expression) 確定序列中的最大值 min(sequence-expression) 確定序列中的最小值 count(sequence-expression) 計算序列中非空值的個數

含嵌入式 SQL 的 XQuery 查詢

問題

有哪些針對位於紐約的商店的評論?將評論的內容顯示為文本。

例子查詢

          xquery 
for $y in 
db2-fn:sqlquery( 
  'SELECT Comments 
   FROM aroma.sales a, aroma.store b 
   WHERE city = ''New York'' 
     AND a.storekey = b.storekey')/Comments/comment/feedback/content/text() 
return $y

結果

Does drinking too much tea cause any health problems? 
How to differentiate from imitations? 
Is there a maximum amount of tea one person can safely consume per day? 
Aroma should consider selling Indonesian House Roast. 
Darjeeling Special was very good. 
Irish Breakfast was great! 
...

關於該查詢

這個查詢將 SQL 嵌入在 XQuery 中,以便根據 SQL 數據值限制結果。這裡沒有使用 db2-fn:xmlcolumn 函數返回一個表的一列中所有的 XML 數據,而是調用 db2-fn:sqlquery 函數,後者執行一個 SQL 查詢,只返回選中的數據。傳遞給 db2-fn:sqlquery 的 SQL 查詢必須返回 XML 數據。然後,XQuery 可以進一步處理返回的 XML 數據。

查詢的 SQL 部分連接 Sales 表和 Store 表。它檢索 Sales 表中與在紐約的商店有相同 storekey 的行。存儲在這些行中的 Comments 文檔成為一個路徑表達式的輸入,該路徑表達式以文本的形式返回文檔中包含的所有 content 元素。

DB2 SQL 與 XQuery 教程,第 7 部分: XML 與 XQuery 簡介 要點:SQL 查詢的 WHERE 子句將 city 值與字符串 "New York" 進行比較。在 SQL 中,這樣的字符串是以單引號括起的。注意,雖然這個例子看上去是使用了雙引號,但實際上是在比較值的前後用了兩個單引號(''New York'')。"額外"的單引號是換碼符。如果在基於字符串的查詢謂詞的前後使用雙引號,而不是使用兩對單引號,那麼就會出現語法錯誤。

結束語

本教程對 XML 和 XQuery 做了基本的概述,討論到了以下問題:什麼是 XML?它有哪些優點?何時應該使用 XML?

然後,本教程向讀者展示了如何使用基本的 Query 查詢來檢索 XML 元素、過濾數據、轉換數據、格式化數據和使用數據。

XQuery 和 SQL 並不是相互排斥的,它們可以聯合起來,形成功能更強大的查詢。

本教程只對 XML 和 XQuery 做最基本的介紹。

本教程是這個 系列 中的最後一個部分。再次感謝您選擇 IBM DB2 9 來了解服務於關系結構和 pureXML 結構的數據的混合型數據服務器。

本文示例源代碼或素材下載

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved