PL/SQL中的 for Update of 应用一例

  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 的话。就不存在这个问题了。

你可能感兴趣的:(测试)