for update 是為當前的查詢加鎖。利用這種方式可以大大的提高效率。下面的一個例子中利用有 for update of 的 遊標更新資料。當然具體效率的提升情況需要用大資料量的處理來測試才能得出來。
declare
cursor gData(var1 varchar2) is select item_name,item_name_en,code_value from y0411 where item_name=var1 for update of code_value;
rs gData%rowtype;
begin
open gData('鋼管');
loop
fetch gData into rs;
exit when gData%notfound;
if rs.item_name='鋁型材' then
update y0411 set code_value='northsnow' Where Current Of gData;
else
update y0411 set code_value='塞北的雪' Where Current Of gData;
end if;
end loop;
close gData;
end;
但是如上的代碼如果改成如下這樣 會出錯。
declare
cursor gData(var1 varchar2) is select item_name,item_name_en,code_value from y0411 where item_name=var1 for update of code_value;
rs gData%rowtype;
begin
open gData('鋼管');
loop
fetch gData into rs;
exit when gData%notfound;
if rs.item_name='鋁型材' then
update y0411 set code_value='northsnow' Where Current Of gData;
else
update y0411 set code_value='塞北的雪' Where Current Of gData;
end if;
commit; ----注意這一句
end loop;
close gData;
end;
錯誤為:ORA-01002: fetch out of sequence
產生錯誤的原因:
在開啟有for update的cursor時,系統會給取出的資料加上獨佔鎖定(exclusive),
而在迴圈中執行了commit語句後,鎖就被釋放了,遊標也變成無效的,再去fetch資料時就出現如上的錯誤了。
因而,應該把commit放在迴圈外,不要在迴圈裡邊commit,等所有資料處理完成後再commit。
當然,如果不用 for update 的話。就不存在這個問題了。