2013-06-21 47 views
3

最後更新:甲骨文選擇工程,更新不,同樣的WHERE子句

事實證明,在我們的情況下,無論如何,這是不是一個錯誤。隱藏在函數調用深處的是一個異常處理程序,它將模糊的錯誤消息指示函數正在發生變化。處理程序將其隱藏起來,並使函數返回基本上有效的值。所以這次是在我們這邊。 :)

原貼:

首先這是真的更多的是好奇,現在,因爲我身邊有一個PL/SQL塊中的問題的工作。但是,我和我的任何同事都不能確定此更新無效。有沒有人有任何想法?

我想用適當的值更新一個新列。以前,記錄的狀態是使用計算需求狀態的函數確定的,我們只是將它轉換爲使用專用表格,允許存儲狀態並提高未來的靈活性。

下面選擇的偉大工程 - 它拉14個記錄:

select * 
from QUERY_TABLE QT1 
where QT1.P_ID in 
    (select QT2.P_ID opi 
    from QUERY_TABLE QT2 
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
     (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value'); 

但是,下面的更新,使用WHERE子句,更新0記錄是相同的:

update QUERY_TABLE QT1 
set QT1.STAT_ID = 1 
where QT1.P_ID in 
    (select QT2.P_ID opi 
    from QUERY_TABLE QT2 
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
     (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value'); 

不知道它會幫助,但下面的PL/SQL塊可以很好地處理更新:

begin 
for x in (
    select QT2.P_ID opi 
    from QUERY_TABLE QT2 
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
     (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value') 

loop 
    update QUERY_TABLE QT1 
    set QT1.STAT_ID = 1 
    where P_ID = x.opi; 
    end loop; 
end; 
/

我已經執行了up日期使用架構所有者和具有適當權限的另一個用戶。表中沒有觸發器會使更新無效。該函數沒有任何奇怪的地方,函數和更新不會互相攻擊(這是一個全新的列 - 函數在語法上與列的值無關)。它不會給出任何錯誤消息 - 它只是更新0列。

UPDATE 1 對於那些可能有同樣問題的人,我們已經聯繫了Oracle,結果發現這是一個新的bug。它已被記錄爲Bug 17015253:具有SUBQUERY中的功能的UPDATE STATEMENT不會更新行,儘管我沒有在知識庫中看到它。

+1

哪個版本的Oracle數據庫?可能與錯誤13936424有關:SELECT FOR UPDATE NOT RETURN VALUES COL for ADD DEFED VALUE&NOT NULL' – ThinkJet

+0

這聽起來很像它可能是答案,我相信這是修復後的版本比我們正在使用11.2.0.2。 – Travis

回答

0

就這樣問題的答案 - 函數中的異常處理程序混淆了錯誤消息,通知我們該函數正在發生變化。這使得它看起來好像函數和語法是有效的。

+0

這會教你不要吞下例外;) –

1

我的經理很棒!她建議加入:
pragma autonomous_transaction;
函數體中的'is'會解決問題。
有關詳細信息,請參閱http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/autotransaction_pragma.htm。例如:

Ex。
功能xyz(...)
   返回VARCHAR2
   是
     編譯AUTONOMOUS_TRANSACTION;
      something varchar2(10);
     。
     。
     。
begin



    return something;
end xyz;