[英]Is using a SELECT inside a pipelined PL/SQL table function allowed?
有關流水線函數的文檔說,在SQL語句(通常是SELECT
)中使用DML時是不允許的,並且在大多數示例中,流水線函數用於數據生成或轉換(接受custor作為參數),但不發布任何DML語句。
現在,從技術上講,可以使用SELECT而不會出現Oracle的任何錯誤(不會發生ORA 14551 )。 但是,我有選擇的可重現的奇怪行為的經驗; 即使未使用PRAGMA AUTONOMOUS_TRANSACTION
,由SELECT
檢索的行似乎也不總是考慮當前的本地事務,這對我來說似乎是個錯誤。 更令人不安的是,當使用分布式事務(例如,通過ORAMTS而不是本地事務)時,會使用該事務。
編輯:事實證明,這種奇怪的效果似乎與查詢中的某些WITH語句有關,有時可能起作用,有時卻不起作用(取決於Oracle優化器的當前狀態,至少在10g中)。 在某些情況下,我得到了ORA-32036,然后再次發生,即使不更改代碼也不會發生。 現在看來,有時因ORA-32036而失敗的查詢也是那些也未能使用正確事務的查詢,並且它可能與流水線功能無關。
所以我的具體問題是:
是否有任何(最好是官方的)聲明是否允許流水線表函數中的SELECT
及其事務上下文是什么?
有沒有其他方法可以模塊化可在SQL語句中使用的常用查詢(就像表函數可以使用TABLE()
)?
有沒有人也經歷過這種行為,也許對此有更多了解? 我已經研究了metalink,但不幸的是,我沒有找到關於該主題的任何具體信息。
通常,DML限制僅涉及修改(UPDATE,DELETE ...)語句,因此SELECT應該可以。 我將嘗試查找Oracle的特定聲明。
視圖將是您使常用查詢模塊化的第一個工具。
函數在視圖方面有一個缺點:如果從另一個SELECT調用它們,則它們不會在與主SELECT相同的時間點執行。 每次對SELECT的調用都是一致的,但是由於SELECT在函數代碼中而不在主SQL中,因此您可能會返回不一致的結果。 對於視圖和子選擇,這是不可能的:如果一個大語句調用一個視圖,則該視圖將在與主查詢相同的時間點構建。
更新 :關於您對參數化查詢的評論
您可以構建參數化視圖,即依賴於執行前設置的變量的視圖。 這是AskTom上的示例,顯示了如何使用userenv('client_info')
或dbms_session.set_context
可以做到這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.