Chinaunix首页 | 论坛 | 博客
  • 博客访问: 508794
  • 博文数量: 101
  • 博客积分: 1635
  • 博客等级: 上尉
  • 技术积分: 1282
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-05 01:51
文章分类

全部博文(101)

文章存档

2019年(2)

2018年(16)

2013年(14)

2012年(69)

我的朋友

分类: Oracle

2012-11-13 21:41:53

一般情况下,如果需要对一个表进行大批量的更新的时候,由于涉及到的记录数很多,所以可能需要花费的时间也就很长,这种情况下,还采用一个单独的update 语句来更新的话,就会造成长时间的加锁,影响到业务。
简单的一个例子,如要更新im_user表中的非空ID为用户表bmw_users中的ID,关联字段为im_user.login_id=bmw_users.nick,语句可以这样写
[php]
update im_user i set i.id=(select id from bmw_users u
where i.login_id=u.nick)
   where i.id is not null;
.
[/php]
这个语句可以更新到几百万记录,当然,耗费时间可能需要1小时以上,对于im_user这样被频繁更新的表来说,肯定是不现实的,所以,该语句可以改写为如下的PL/SQL块。
[php]
declare
  row_num number := 0;
begin
for c_usr in (select login_id from im_user t where id is null) loop
   update im_user i set i.id =
     (select id from bmw_users u where i.login_id = u.nick)
   where login_id = c_usr.login_id;
   row_num := row_num + 1;
   if mod(row_num,100) =0 then
     commit;
   end if;
end loop;
commit;
end;
/
.
[/php]
这样的话,因为每更新100条就提交1次,对表的影响相对是很小的,而且,如果是一个语句,如果中途执行失败,将导致回滚,同样要耗费很长时间,但是这种情况下,因为是一边执行一边提交,基本可以分很多次来操作,之间不会有影响。
阅读(825) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~