2013-06-03 54 views
0

當我在我的Oracle SQL Developer請調試以下Oracle SQL過程

create or replace 
Procedure Table_Update 

IS 
    s_id VARCHAR2(256 byte); 

    CURSOR C1 IS 
    SELECT A.SR_ID 
    FROM TABLE_2 B,TABLE_1 A 
    WHERE A.Primary_key=B.Primary_Key; 

BEGIN 
loop 
    open c1; 
    fetch c1 into s_id; 

    exit when C1%NOTFOUND ; 

    update TABLE_2 set SR_ID = s_id;  

    commit; 

    END LOOP; 

CLOSE C1; 
END; 

運行下面的過程中TABLE_1和TABLE_2這裏有類似structure.My要求從TABLE_1 SR_ID應TABLE_2基礎上進行更新相匹配的主key.When我運行的程序,我得到了以下錯誤消息

Connecting to the database XXX. 
ORA-06511: PL/SQL: CURSOR ALREADY OPEN 
ORA-06512: at "Table_Update", line 7 
ORA-06512: at "Table_Update", line 13 
ORA-06512: at line 2 
PROCESS EXITED. 
Disconnecting from the database XXX. 

我已經嘗試這種遍地請幫我

謝謝

+1

我不是專家,但我認爲YOUE缺少'where'在'update'聲明條款。 – haki

+0

另外一點,除了a_horse_with_no_name的優秀答案,如果你願意這樣做,即你有一個500米的行表,並且不能鎖定整個事物,那麼最好使用BULK COLLECT並更新ROWID要快得多。 – Ben

回答

3

移動open c1;在循環的外面,你只需要打開它一次。

+0

我試過這樣做,創建或替換 過程Table_Update IS s_id VARCHAR2(256字節); CURSOR C1 IS SELECT A.SR_ID FROM TABLE_2 B,TABLE_1 A WHERE A.Primary_key = B.Primary_Key; open c1; BEGIN loop 將c1讀取到s_id中; C1%NOTFOUND時退出; update TABLE_2 set SR_ID = s_id; 提交; END LOOP; CLOSE C1; END;我收到一條錯誤消息(11,10)項目被忽略並且錯誤(11,10)'c1'必須是 – Sudhan

+0

@Sudhan類型,結果是?閱讀a_horse_with_no_name的答案。 – Roger

+0

可能是你可以看到我的編輯評論現在 – Sudhan

4

羅傑已經說過:移動光標的開環之外。

但同樣重要的是:不要在內部提交。這會讓事情變慢,給數據庫帶來更多壓力,同時也會關閉遊標。

但更重要的是:你根本不需要循環。您可以在一個單一的更新語句做到這一點:

update TABLE_2 
    set SR_ID = (select a.sr_id 
       from table_1 a 
       where a.primary_key = table_2.primary_key); 

或交替使用merge聲明:

merge into table_2 
using table_1 a 
    on (table_2.primary_key = a.primary_key) 
when matched then update 
    set sr_id = a.sr_id; 

這將是快了很多,然後將光標爲基礎的方法。

這裏是一個SQLFiddle:http://sqlfiddle.com/#!4/0b810/1

+0

+1:或從TABLE_1的外鍵TABLE_2主鍵列的更新可以針對連接兩個表的運行。 –

+0

+1替代方案和見解。不過,我相信他只需要使用WHERE子句更新他打算的記錄。但這並不明確,OP可能會感到困惑。 – Roger

+0

@Roger:根據問題的任擇議定書要更新所有行TABLE_2有基於該主鍵sr_id相同的值。我不認爲'WHERE'子句是必要的,但它可以很容易地在兩個版本中應用。 –