簡體   English   中英

Oracle SQL-從XML標記中選擇一個日期並將其轉換為DATE類型以允許比較日期

[英]Oracle SQL - Selecting a date from an XML tag and casting it to a DATE type to allow comparison of the dates

我有一個存儲XML文檔的CLOB類型列(稱為xml)。 xml文檔具有名為<productionDate>的標記。

我想做的是搜索表並檢索包含兩個日期之間具有productionDate的xml文檔的任何行。

我知道如何讀取xml標記作為值:

Select 
xmltype(xml).extract('//product/productionDate/text()').getStringVal() from myTable

上面的查詢返回以下日期。

1999-09-23 00:00:00.0 UTC
2000-01-18 00:00:00.0 UTC
2000-01-18 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC
1999-11-02 00:00:00.0 UTC

我只列出1999年11月1日至2000年1月1日之間的內容。 為此,我嘗試將值轉換為DATE類型

Select 
XMLCast(xmltype(xml).extract('//product/productionDate/text()').getStringVal() as DATE) from myTable

我收到以下錯誤:

ORA-01830: date format picture ends before converting entire input string

大概是因為日期格式無法轉換為日期格式。 我該怎么做才能將日期讀取為有效日期(忽略時間和UTC文本),以便可以對日期進行比較。

也許一個子串可能有效,但是我想聽聽那里還有哪些其他更有效的選擇。

您以字符串形式獲取值,因此您應該只能使用to_dateto_timestamp

Select 
  to_timestamp(xmltype(xml).extract('//product/productionDate/text()').getStringVal(),
    'YYYY-MM-DD HH24:MI:SS.FF "UTC"')
from myTable

SQL Fiddle演示

如果需要,可以同時將其移至其他時區。

當然,給定日期格式,您可以將其作為字符串進行比較並跳過轉換...

用於基於文件的數據類型的查詢優化的窮人方法

有多種方法可以優化基於文件的數據類型(CLOB / XML)的存儲和檢索。 如果您使用Oracle等關系數據庫解決方案,這里有一些簡單的建議,這些建議使用即用型功能,而無需購買,許可或安裝其他附加組件和產品。

初步思路:有關流量和使用的思考

它可以幫助您考慮需要多長時間探查XML文件以提取其屬性。 考慮這些XML文件的內容一旦添加到基於CLOB的表中后,更改的頻率也很重要。

如果涉及CLOB類型表的DML通信量不太高,請考慮構建一個輔助對象,該對象的鈎子類型將幫助您在需要時找到正確的XML文件。 有了它之后,就可以將查詢活動從源表轉移到特定的基於主鍵的查詢之外。

內聯函數轉換及其優化

話雖如此,您可以即時應用轉換函數並在每次查詢時轉換日期值。 甚至還有用於Oracle的加載項,它們可以優化數據庫以查詢和搜索LOB對象中的值。

甚至還有一個稱為FUNCTION BASED INDEX的優化約定,它提示Oracle使用備用引用(索引),該備用引用也使用TO_DATE / SUBSTR函數組合,您需要在XML文檔中轉換值。

對於INLINE轉換,還有其他方法可能會好得多,因為每次調用查詢時都會應用INLINE轉換。 通常,沒有轉換功能和原始格式的數據(即日期作為日期,日期時間或時間戳記)以更快的速度運行,而現有數據庫資源的成本卻更低。

從外部標記您的XML文檔

假設帶有XML文件的CLOB表也有一個主鍵列,那么會想到兩個想法:

  1. 使用轉換后的值(例如PRODUCTION_DATE )創建第二個表,並使用其來源的CLOB的PK ID標識每個日期記錄。 當您發現查詢經常訪問的新屬性時,可以擴展該表。 通過在CLOB表上放置觸發器來管理第二個表。

    每當添加Clob記錄時,數據值就被提取並轉換一次。 如果有任何查詢未更改的Clob記錄,則自上次查詢以來,就無需提取和轉換該值。

  2. 創建包含提取和轉換功能的實例化視圖,以便可以將PRODUCTION_DATE的MView列定義為實際的DATE類型。 MView也可以像Idea(1)一樣工作,但是要優雅一些。

    如果可能,FAST可刷新視圖將很好地工作,因為它可以自動管理MView並幾乎實時響應CLOB表中的更改。 FAST可刷新視圖僅使用更改和添加來更新MView,因此,即使源表很大,日常操作也僅基於增量效果。

不了解數據的數量,使用情況或狀態,如果沒有其他折衷或假設,完全刷新類型MView可能會或可能不會有效。 有時,MView查詢定義太復雜而無法使用FAST可刷新格式。

無論哪種情況,您最終都會得到另一個對象(MVIEW或TABLE),該對象包含PRODUCTION_DATE的DATE格式值。 而是查詢此TAG表,並使用關聯的PK值來確定在縮小滿足查詢條件的集合或單個記錄后應訪問CLOB表中的哪個記錄。

離別的想法(可選...有點)

如果可能具有NULL PRODUCTION_DATE值,那么在查詢TAG支持表時僅應用NVL()內聯函數將很誘人。 根據所討論的數據量,這可能不應該成為問題。 理想情況下,您將始終希望在那里擁有一個值...並在該DATE列上具有NOT NULL約束...這些事情可以幫助db優化器對如何深入表進行更好的假設...特別是如果那里有很多記錄。

總之,您還可以使用XMLTYPE數據類型,該數據類型實際上是為處理XML而優化的。 而且它將比您想象的要勝過更多的替代解決方案。 不需要窮人的解決方案(如果不僅如此,在8i / 9.1 / 9.2數據庫版本中,這也是一個糟糕的“解決方案”)。 也就是說,XML(DB)是可以免費使用的“無成本選擇” /不需要額外的許可證。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM