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

當行與列不能滿足需要時

2022-06-13   來源: Oracle 

  使用原生XML(native XML)特性處理不斷變化的數據結構
  
  在處理不完全符合關系模型要求的數據或者應用程序必須處理隨時間而改變的數據結構時你會怎麼做呢?
  
  在本專欄中我將闡明我是如何使用Oracle XML DB的特性來創建一個原型系統的它無需重新編碼便能適應新的及改變了的數據結構我還將介紹Oracle的DevTrends網站上的工作示例代碼
  
  Oracle XML DB是Oraclei第二版(或更高版)的一組特性它為存儲定位和查詢XML文檔提供了原生支持
  
  應用程序要求
  
  該原型系統將存儲並轉發政府機構所使用的管理文檔(表格狀態報告簡報等)很高興這些文檔將用XML進行編碼但仍存在著一系列難以應對的需求
  
  這些文檔的數量類型及內容經常改變
  
  該系統必須同時處理新舊兩種文檔類型
  
  這些文檔有時含有多信息文本(rich text)包括HTML標記
  
  數據是在多個不同位置輸入的所以我需要信息域幫助解決數據分布問題
  
  將來系統遲早要支持數字簽名
  
  設計要點
  
  即使該系統處理的文檔類型會隨時間變化我仍然希望能夠在存儲XML文檔時對它們進行驗證因此每一種文檔類型都需要對定義它的相應XML模式進行注冊
  
  使用Oraclei XML DB可以將XML文檔分解成關系對象(結構化存儲)或者只是將這些文檔整個存儲為CLOB(非結構化存儲)兩種方法都利用了原生的XMLType服務器類型從而支持XPath表達式與訪問方法
  
  因為該系統必須能夠適應新的文檔類型而不需改變代碼所以文檔將存儲為CLOB
  
  但只存儲XML文檔自身是不夠的處理文檔驗證的代碼庫以及系統的持久性同步和管理取決於某些其他數據元素如全局主關鍵字日期/時間標記最初位置及正在處理的文檔類型這些元素即文檔屬性必須與在不同位置間發送的XML文檔共存所以需要一個屬性模式來包含它們
  
  有兩種方法可以將XML文檔同文檔屬性關聯起來一種是簡單地將文檔屬性元素包含在各個文檔模式之中這種方法提供了一種相當扁平的結構它使XPath表達式較短但我卻不能處理別人創建的模式另一種方法是將XML文檔包裝在另一個含有所需屬性的XML文檔中這種方法需要分別驗證包裝文檔和內容文檔但它會提供所需要的靈活性
  
  創建XML模式
  
  我的工作將從創建既能表示包裝文檔又能表示內容文檔的XML模式開始
  
  首先從包裝文檔開始創建一個XML模式它包含所需的全部文檔屬性和一個用於內容文檔的占位符(利用任一元素類型)所有的文檔屬性都根據屬性元素進行分組我可以用KeyName元素為文檔命名以便檢索Schema和Element元素指示Content元素中所包含的文檔類型
  
  通過Oraclei XML DB可以使用一組特定的模式注釋對設置內部存儲的方式進行定制我可以指定每個元素的存儲類型為所創建的表和類型提供數據庫名
  
  在這樣的情況下我想混合使用結構化的XML文檔存儲與非結構化的XML文檔存儲將內容存儲為原生XML將文檔屬性存儲為對象關系類型我將為DOCUMENTS設定defTable屬性並給出各Properties元素的SQLName值對於Content元素我打算將存儲類型設為CLOB它表示非結構化的XML存儲當此模式向數據庫注冊時XML DB將依照模式注釋創建對象關系類型
  
  接下來為了驗證置於Content元素中的文檔的各個類型還需要為各個文檔類型准備一個XML模式
  
  我想跟蹤該系統所能處理的所有內容類型所以我會創建一個存儲程序來注冊內容模式該程序會記錄內容類型名和TYPES表中的其他細節然後向XML DB注冊該模式因為我在上一步中已經為這些文檔創建了CLOB存儲所以當我使用該程序為內容注冊任何一種模式時該程序都會告訴XML DB不要創建任何新表或對象類型
  
  Dbms_xmlschemaregisterSchema(
  schemaURL => schema_url
  schemaDoc => schema
  local => true
  genTypes => false
  genTables => false)
  
  插入數據
  
  現在我將插入一個新文檔為了更輕松我要創建一個存儲程序它將)檢查文檔內容是否已注冊)驗證文檔)用一般XML包裝文件包裝文檔並填充屬性元素)將文檔插入數據庫要插入一個新文檔只需要像下面這樣調用該程序
  
  dtx_docsave(xmltype(
  getDocument(incidentxml))
  Incident)
  
  getDocument()調用是一個實用程序它基於Oraclei XML數據庫開發人員指南附錄G中的示例代碼它作為一個CLOB從文件系統載入文檔第二個參數save()的代表KeyName元素將被用於在文檔上建立索引
  
  一個突出的XML DB特性是能夠在XML文檔存儲表上創建基於函數的索引如下所示
  
  CREATE INDEX ix_keyname
  ON documents d (dextractValue(
  /Document/Properties/KeyName));
  
  檢索數據
  
  現在可以對DOCUMENTS表運行基於XPath的查詢但如果創建一個XML文檔存儲的關系視圖如清單 所示就能通過標准SQL來訪問結構化的存儲那麼查詢就會更容易這樣也可以更輕松地查詢文檔屬性
  
  現在可以直接查詢該視圖以查看文檔屬性
  
  清單 中的Print_table()過程是Tom Kyte()編寫的一個實用程序它可對查詢進行縱向格式化 它與本專欄的示例代碼一起放在了網上
  
  除了通過SQL調用檢索數據外也可以利用內建於該數據庫中的Oracle XML DB HTTP協議服務器檢索文檔如果你的數據庫監聽程序正在運行你可以在浏覽器中輸入以下URL以查看插入文檔的完整XML
  
 //localhost:/oradb/
  DTXDOCS/DOCUMENTS
  
  DTXDOCS是我的數據庫用戶名我也可以在URL中置入一個XPath查詢並指定一個XML樣式表它會把XML轉換為格式優美的HTML文檔
  
 //localhost:/oradb/DTXDOCS/
  DOCUMENTS/ROW/Document
  [Properties/Subject=Incident]
  ?transform=/public/dtxdocs/incidentxslt
  &contenttype=text/html
  
  示例代碼
  
  在DevTrends網站上我已經放置了用於說明本文簡述概念的示例代碼
  
  其中的說明腳本會告訴你我創建用於應用程序的內部工作的單一代碼庫以及根據需要向系統注冊新文檔類型的方法由於我在實際文檔中沒有使用結構化的存儲所以這種方法也可能多少會有助於解決模式發展的問題
  
  Cameron ORourke (camero) 擔任Oracle 技術專家已超個
From:http://tw.wingwit.com/Article/program/Oracle/201311/17623.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.