2013-02-12 33 views
2

這個問題與我的previous question有關。

執行一個函數內部的程序(ORA-14551錯誤)

我有一個程序(PROC_YEARLYACTIVELIST2),它將顯示在指定年份處於活動狀態的所有記錄。
它將刪除以前的內容TBLACTIVELISTYEARLY2並從PROC_YEARLYACTIVELIST2中插入結果。

我創建了一個函數,它將執行TBLACTIVELISTYEARLY2,從TBLACTIVELISTYEARLY中選擇所有記錄並將其放入CURSOR C_IH,然後返回Crystal Report報表。

下面只是部分代碼:

 

DECLARE 
    CURSOR C_IH IS SELECT * FROM tblActiveListYearly2; 

    ctr INT; 
    i NUMBER; 
    currDeploymentComputer COL_TYPE_DEPLOYMENT_COMPUTER := COL_TYPE_DEPLOYMENT_COMPUTER NULL); 
    R_IH C_IH%ROWTYPE; 

BEGIN 
PROC_YEARLYACTIVELIST2(in_year); 

    OPEN C_IH; 
    i := 0; 
    LOOP (....) 

我試圖調用該函數爲

SELECT GETDEPLOYMENT_COMPUTER('2012') from dual; 

,並具有ORA-14551錯誤

ORA-14551: cannot perform a DML operation inside a query 
ORA-06512: at "NPLS.PROC_YEARLYACTIVELIST2", line 12 
ORA-06512: at "NPLS.GETDEPLOYMENT_COMPUTER", line 3 

搜索了它並發現它是因爲與發生衝突,UPDATEDELETEDUAL

是否有任何其他方式來執行我的過程中將返回一個表的函數?

謝謝!

+1

閱讀關於自治事務。不漂亮,但可能是您的情況的唯一解決方法。 – 2013-02-12 07:25:41

+0

謝謝@a_horse_with_no_name的迴應! :) – 2013-02-13 01:34:55

回答

1

我認爲你需要分離DML變更和報告部分。做數據更改的過程應該在您的報告函數調用之外調用...

+0

但是如何?我可以把我的程序放在我的水晶報告中,但我猜crystal不能處理oracle查詢。所以,我試圖創建一個只返回表的函數。嗯,我可以使用流水線或包裝功能,或者什麼?你能給我一個建議嗎?謝謝! – 2013-02-12 06:39:01

+1

你可以嘗試另一種方法 - 而不是chaging表數據 - 只需選擇你所需要的? – igr 2013-02-12 07:42:02

+0

是的,你是對的。我只是無視DML和使用表格。感謝您的迴應! :) – 2013-02-13 01:33:47

2

否;由於非常好的原因,您在不能在SELECT語句中執行DML。

您正在更改數據庫中的數據,Oracle需要數據的讀取一致性視圖,即它需要知道您選擇的內容沒有被您選擇的內容改變。

你在做什麼聽起來非常不必要;你有3個步驟:

  1. 從表中刪除一些數據
  2. 新數據插入到該表從表
  3. 選擇數據。

爲什麼不簡單地選擇你需要的數據;它會更快?如果您必須預先處理數據,那麼您可以有一個與選擇數據異步執行此操作的過程。

我對Crystal Reports一無所知,但您也可以在PL/SQL塊中執行此操作。

declare 
    l_getdeployment my_variable_type; 
begin 
    l_getdeployment := GETDEPLOYMENT_COMPUTER('2012'); 
end; 
/
+0

是的,你是對的!我只是選擇我想要的,並使用函數返回。並無視'TBLACTIVELISTYEARLY2'。感謝您的答覆! :) – 2013-02-13 01:37:27

0

這太複雜了。
因爲我想從表格中獲取記錄到水晶報告,我把我選擇的東西放到一個表格中。現在

,我意識到,我可以將邏輯從我的程序寫入功能,把它變成一個SYS_REFCURSOR,返回並使用此查詢調用函數:

SELECT * FROM TABLE(GETDEPLOYMENT_COMPUTER('2012')); 

謝謝你,反正,對於那些迴應並幫助我的人。 :)