熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

關於如何更新 XQuery 的具體步驟介紹

2013-11-13 22:19:20  來源: Oracle 

  更新XQuery
  XQuery有了一些新特性內容包括從原子化到跟蹤文件結構
  
  在你所不了解的XQuery(Oracle雜志/月刊)一文中我介紹了XQuery它是一項由萬維網聯盟(WC)開發的技術設計用來查詢和操縱XML數據或任何能以XML形式出現的數據如關系型數據庫那篇引文討論了月發布的XQuery草案規范WC發布了新的XQuery草案規范本文追蹤報道了月份發布的草案規范中最令人感興趣的變化和新增加的特性其中包括庫模塊序(prolog)變量外部函數以及用於調試錯誤處理和格式化的新函數
  
  變化
  月草案增加了大量新特性但是我首先討論對現有特性所做的更改有些更改是表面上的 例如document()輸入函數(該函數使用給定的統一資源標識符[URI]返回一個文檔)被改為一個新的更短的名字doc()另外曾經被寫成{ comment }的注釋現在改用新的笑臉符號(: comment :)是的現在每個注釋都成了一個笑話
  
  有些更改則是更根本的也許最重大的改動就是distinctvalues()函數不再返回節點(節點是XML結構如元素文檔注釋以及文本節點)它只返回原子值(如整數或字符串)盡管該函數仍然接受節點和原子值但只返回原子值任何進入該函數的節點都會被原子化並被當作原子值然後以原子形式返回
  
  原子化的規則很復雜這裡給出一些基本的由模式定義為布爾型的元素將被原子化為true/false布爾值定義為整型的元素將被原子化為一個整數沒有被模式定義的元素將被原子化為節點的XPath字符串值(文本節點遞歸地連接在一起)
  
  為了說明
  distinctvalues(<item>apple</item>
  <item>banana</item> grape)
  
  返回值(applebananagrape假設在模式中沒有聲明 在下面的例子中如果我們假設 被模式定義為布爾型那麼下面的語句
  
  distinctvalues(<status></status>
  <status>false</status>)
  
  返回false()因為它是兩個元素的原子值記住false()是XQuery常量表示
  
  現在你也許會想當我想返回節點時可以使用distinctnodes()函數 是的但該函數只能根據節點標識刪除重復節點(那些完全相同的節點類似於Java中引用的等效節點)沒有能刪除等效節點的函數這會使查詢變得復雜因為沒有辦法能輕松地刪除等效節點
  
  回過頭來看我以前的那篇文章你所不了解的XQuery你將發現有些示例會受到這一改動的影響在那篇文章中下面的查詢返回了藝術家名字的惟一列表其中每一個名字前後都帶有 標記
  
  distinctvalues(document(itunesxml)
  /itunes/Tracks/Track/Artist)
  
  示例輸出類似於
  
  <Artist>Marc Cohn</Artist>
  <Artist>Pink Floyd</Artist>
  
  現在執行同樣的查詢則返回原子值
  
  Marc Cohn
  Pink Floyd
  
  由於distinctvalues()去掉了 標記(這是原子化過程的一部分)所以你必須在完成distinctvalues()調用後添加標記如下所示
  
  let $artists :=
  distinctvalues(doc(itunesxml)
  /itunes/Tracks/Track/Artist)
  for $a in $artists
  return <Artist>{ $a }</Artist>
  
  不是每種情況都是這麼輕松地得到處理看一下WC 使用案例文檔中的示例月版與月版中是如何變化的該示例返回每位作者的著作列表它使用了distinctvalues()根據月的規范它的代碼如下
  
  <results>
  {
  for $a in distinctvalues(
  document()
  //author)
  return
  <result>
  { $a }
  {
  for $b in document(
  )
  /bib/book
  where some $ba in $b/author
  satisfies deepequal($ba$a)
  
  ; return $b/title
  }
  </result>
  }
  </results>
  
  根據查詢結果你不能直接分辨出姓和名但每個 元素都由一個 和 名組成distinctvalues()調用返回具有惟一名字的 元素列表對於月的規范現在查詢必須在姓和名上單獨運行distinctvalues()而且在嵌套的FLWOR表達式中也沒有將$a指定為惟一的作者
  
  <results>
  {
  let $a :=
  doc()
  //author
  for $last in distinctvalues($a/last)
  $first in distinctvalues(
  $a[last=$last]/first)
  return
  <result>
  { $last $first }
  {
  for $b in
  doc()
  /bib/book
  where some $ba in $b/author
  satisfies ($ba/last = $last and
  $ba/first=$first)
  return $b/title
  }
  </result>
  }
  </results>
  
  除了編寫用戶定義的distinctdeepequal()外沒有更好的方法來完成這件事了而該方法在純XQuery中不能執行(注FLWOR(發音為flower)表達式是XQuery的構建模塊這個名字來源於組成表達式的關鍵詞ForLetWhereOrder by和Return}
  
  新函數
  月的XQuery規范草案增加了三個新函數它們肯定會非常有用第一個是
  
  trace($value as item()*
  $label as xs:string) as item()*
  
  trace()函數允許在查詢的中間進行printf風格的調試該函數有兩個參數要顯示的值(可以是任意多個項的序列)以及要顯示的這個值的字符串標簽為方便起見函數返回$value傳遞的值trace()輸出的位置由你的引擎來決定
  
  該函數使你能夠詳細查看查詢的內部過程例如下面的查詢根據文檔名返回在XQuery引擎中存儲的所有文檔的URI通過增加一個trace()調用我能夠在排序前查看返回的每個URI
  
  define function uris() as xs:string* {
  for $n in input()
  return trace(
  xs:string(documenturi($n)) base:)
  }
  for $u in uris() order by $u return $u
  
  輸出結果可能如下
  
   :: base: censusxml
   :: base: ipoxml
  
  當使用trace()和其他類似的函數時記住在XQuery中每項內容都是一個表達式沒有語句!為了能夠完成類似語句的操作你可以采用在表達式之間加逗號的方法來創建一個序列然後單獨計算每個表達式的值在最終的結果序列中忽略所有返回空值的表達式例如下面是兩個不影響結果的trace()調用
  
  trace(() starting query)
  
  let $time := currentdateTime()
  let $ignored := trace($time Got time)
  return
  <html>
  <head></head>
  <body>Current time is { $time }</body>
  </html>
  
  請注意第一個trace()調用後面的逗號它使查詢返回一個具有兩個項的序列第一個trace()調用的結果為空因而被忽略一般人不了解這一情況但高級查詢實際上就是返回一個序列因此在這種特殊情況下兩端的括號不是必需的查詢 是完全正確的此外在這個示例中你會看到當編寫一個FLWOR表達式時你可以執行let子句右側的任意代碼並且忽略該值
  
  月份的草案還增加了error()函數
  
  error($srcval as item()?)
  
  這個函數使用戶能夠報告一個錯誤類似於拋出一個異常$srcval被定義為item()?意味著它可以是一個XML結構或原子並且加上問號標記表示這是可選的下面是一些示例應用
  
  error()
  error(Missing source document)
  error(<span>A <i>beautifully</i>
  formatted error</span>)
  
  error()調用就像發生異常時那樣展開堆棧遺憾的是XQuery仍沒有try/catch功能因此盡管你能拋出錯誤但卻不能從中恢復
  
  在月份的草案中最後一個引人注目的新增函數有一個奇怪的名字roundhalftoeven()它有兩種形式
  
  roundhalftoeven($srcval as numeric?)
  as numeric?
  roundhalftoeven($srcval as numeric?
  $precision as xs:integer) as numeric?
  
  在有一個參數的情況下它的行為類似於round()函數只是當一個數恰好落在其他兩個數的中間時它將參數取整為最接近的偶數值數字理論家們會告訴你從統計學上講這是一個更精確的取整算法舉例說明
  
  roundhalftoeven() =
  roundhalftoeven() =
  roundhalftoeven() =
  
  有第二個參數的情況使函數變得很有趣第二個參數表示精確級並允許將函數用於格式化小數值例如
  
  roundhalftoeven( ) =
  roundhalftoeven( ) =
  roundhalftoeven( div ) =
  
  在聲明中使用的數字數據類型是xs:decimalxs:integerxs:floatxs:double以及任何根據限制由它們導出的類型的一種簡單表示它用於XQuery規范中但你不能在自己的查詢中使用它
  <
From:http://tw.wingwit.com/Article/program/Oracle/201311/18764.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.