Posted on 2010-05-10 23:04
Prayer 阅读(396)
评论(0) 编辑 收藏 引用 所属分类:
DB2
基本用法:
cursor c1 is
select *
from tablename
where name is null
for update [of column]
……
for r1 in c1 loop
update tablename
set column = …… --已限制了条件了,更新只是当前记录集
where current of c1;
end loop;
where current of 子句只能在定义游标的时候使用了for update语句才可以使用。
上面的语句中r1 是c1中的一行数据,更新的时候应该用current of c1,因为c1只是一个隐式游标,它本身不是通过for update定义的,只是代表了循环中的当前记录。这样,你的update语句或者delete语句的作用范围就只在你循环的当前行的范围中了。
要注意的是,用for update定义的游标会让数据库对涉及的行加锁,别的会话如果要访问该游标中的行便会进入等待状态。你也可以明确指明要加锁的列,用for update of "列名" 就可以了。
如果select for update选中的行已经被别的会话加锁的话,会话就需要等待解锁,如果别的会话一直不解锁,那么你的select就会一直等待下去,如果你不想等,只需在for update后面加上nowait就可以解决这个问题了,这样你的选择会立即返回。
针对where current of的使用和我们日常的更新方法,进行了一个简单的测试。
编写了两个简单的过程,比较使用where current of和不使用时,性能的差异。
SQL> create table t
2 as
3 select * from all_objects;
表已创建。
SQL> create table t1
2 as
3 select * from t;
表已创建。
SQL> select count(*) from t;
COUNT(*)
----------
37003
SQL> exec runstats.rs_start;
PL/SQL 过程已成功完成。
SQL> declare
2 cursor sal_cursor is
3 select object_name
4 from t
5 for update nowait;
6 begin
7 for i in sal_cursor loop
8 update t
9 set data_object_id = data_object_id + 1
10 where current of sal_cursor;
11 end loop;
12 end;
13 /
PL/SQL 过程已成功完成。
SQL> exec runstats.rs_middle;
PL/SQL 过程已成功完成。
SQL> declare
2 cursor sal_cursor is
3 select object_name
4 from t1
5 for update nowait;
6 begin
7 for i in sal_cursor loop
8 update t1
9 set data_object_id = data_object_id + 1
10 where object_name = i.object_name;
11 end loop;
12 commit;
13 end;
14 /
PL/SQL 过程已成功完成。
SQL> exec runstats.rs_stop(1000000);
Run1 ran in 3767 hsecs
Run2 ran in 126597 hsecs
run 1 ran in 2.98% of the time
Name Run1 Run2 Diff
STAT..no work - consistent rea 37,268 9,212,891 9,175,623
STAT..table scan blocks gotten 37,247 9,212,999 9,175,752
STAT..buffer is not pinned cou 37,282 9,213,043 9,175,761
STAT..consistent gets 37,311 9,400,510