2011-06-08 65 views
2
declare 
type array is table of src%rowtype index by binary_integer; 
l_data array ; 

begin 

loop 

    begin 
     select * bulk collect into l_data 
     from src 
     where processed = 'N' 
     and rownum < 10 
     for update of processed; 
     exit when sql%rowcount = 0; 
    exception 
     when no_data_found then exit; 
    end; 

for i in 1 .. l_data.count 
    loop 
     update tgt set x = l_data(i).x , y = l_data(i).y where rowid = l_data(i).tgt_row_id ; 
     update src set processed = 'Y' where tgt_row_id = l_data(i).tgt_row_id; 
    end loop; 

commit; 



end loop; 

end; 
/

我編輯了代碼以使用批量收集,但它只是掛在11.2中。提交在循環中

SQL> select * from src; 

     X Y   TGT_ROW_ID   P 
---------- ---------- ------------------ - 
     1 ABC  AAAWZDAAEAAAA1EAAA Y 
     1 DEF  AAAWZDAAEAAAA1EAAA Y 
     2 ABC  AAAWZDAAEAAAA1EAAC Y 

SQL> select * from tgt; 

     X Y 
---------- ---------- 
     1 ABC 
     1 
     2 ABC 
+3

您的問題是什麼? – YXD 2011-06-08 14:34:39

+0

抱歉,我不確定我無法格式化這個 – lisa 2011-06-08 14:38:38

+1

@Lisa我編輯了您的問題。只是你知道,要格式化代碼,所有你需要做的就是選擇文本按下'{}'按鈕 – 2011-06-08 14:40:48

回答

1

這裏確實存在幾個問題。

1)上線10的錯誤這是因爲需要使用BULK COLLECT選擇到一個數組:

select x,y,tgt_row_id 
bulk collect into l_data 
from src 

然而,由於L_DATA使用src%rowtype上述只能如果表中有定義只是3列x,y,tgt_row_id。當使用%rowtype時,它實際上是更好使用select *,因爲它肯定會匹配記錄結構。

2)你的循環永遠不會退出。您需要添加如下內容:

loop 
    select * bulk collect into l_data 
    from src 
    where processed = 'N' 
    and rownum < 10 
    for update of processed; 

    exit when sql%rowcount = 0; 
    ... 
end loop; 
+0

我嘗試了你的建議,但代碼沒有在oracle 11.2.0.1版本上提示sql提示符 – lisa 2011-06-08 15:20:40

+0

你的代碼因爲沒有退出循環而掛起,所以如果沒有錯誤,它會永遠運行!你確實有一個NO_DATA_FOUND的異常處理程序,但是這對BULK COLLECT不起作用。 – 2011-06-08 15:26:35

+1

爲了在沒有匹配的行時退出,你可以在select之後立即'在sql%rowcount = 0時退出'。但是如果你確實匹配任何行('processed ='N''),那麼它仍然會永遠循環,因爲你實際上並沒有更新爲「Y」。每次循環查詢都會得到相同的未處理行。你必須對你選擇的數據做些什麼。 – 2011-06-08 15:37:45