[英]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_date
或to_timestamp
:
Select
to_timestamp(xmltype(xml).extract('//product/productionDate/text()').getStringVal(),
'YYYY-MM-DD HH24:MI:SS.FF "UTC"')
from myTable
如果需要,可以同時將其移至其他時區。
當然,給定日期格式,您可以將其作為字符串進行比較並跳過轉換...
有多種方法可以優化基於文件的數據類型(CLOB / XML)的存儲和檢索。 如果您使用Oracle等關系數據庫解決方案,這里有一些簡單的建議,這些建議使用即用型功能,而無需購買,許可或安裝其他附加組件和產品。
它可以幫助您考慮需要多長時間探查XML文件以提取其屬性。 考慮這些XML文件的內容一旦添加到基於CLOB的表中后,更改的頻率也很重要。
如果涉及CLOB類型表的DML通信量不太高,請考慮構建一個輔助對象,該對象的鈎子類型將幫助您在需要時找到正確的XML文件。 有了它之后,就可以將查詢活動從源表轉移到特定的基於主鍵的查詢之外。
話雖如此,您可以即時應用轉換函數並在每次查詢時轉換日期值。 甚至還有用於Oracle的加載項,它們可以優化數據庫以查詢和搜索LOB對象中的值。
甚至還有一個稱為FUNCTION BASED INDEX的優化約定,它提示Oracle使用備用引用(索引),該備用引用也使用TO_DATE / SUBSTR函數組合,您需要在XML文檔中轉換值。
對於INLINE轉換,還有其他方法可能會好得多,因為每次調用查詢時都會應用INLINE轉換。 通常,沒有轉換功能和原始格式的數據(即日期作為日期,日期時間或時間戳記)以更快的速度運行,而現有數據庫資源的成本卻更低。
假設帶有XML文件的CLOB表也有一個主鍵列,那么會想到兩個想法:
使用轉換后的值(例如PRODUCTION_DATE )創建第二個表,並使用其來源的CLOB的PK ID標識每個日期記錄。 當您發現查詢經常訪問的新屬性時,可以擴展該表。 通過在CLOB表上放置觸發器來管理第二個表。
每當添加Clob記錄時,數據值就被提取並轉換一次。 如果有任何查詢未更改的Clob記錄,則自上次查詢以來,就無需提取和轉換該值。
創建包含提取和轉換功能的實例化視圖,以便可以將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.