Welcome 微信登录

首页 / 数据库 / MySQL / 关于Oracle中update

前几天用到Oracle数据库的update更新,对于这个简单问题,却出现了不少问题,所以现将从网上搜索资料及自已的总结罗列在此以备一时之用.以下所列sql都是基于下表create table test (name  varchar2(30),code varchar2(10),i_d varchar2(10));插入数据insert into test(name,code,i_d) values("zhu1","001","1");
insert into test(name,code,i_d) values("zhu2","002","2");
insert into test(name,code,i_d) values("zhu3","003","3");
commit;
select * from test s; 1. update 更新i_d为1的数据--方式1
update test  set name="zhurhyme1",
code="007" where i_d="1";
commit;这样可以成功--方式2update test set (name,code)=(
"zhurhyme2","007")
where i_d="1";注意,这样是不行,update set 必须为子查询,所以需要将其改为 :--方式3update test set (name,code)=(
select "zhurhyme3","007" from dual)
where i_d="1";commit;2.update 说完了,下面写一下关于for update,for update of  下面的资料是从网上找到的,可是具体的网址现在找不到了,请原谅小弟的粗心,引用人家的东东而不写出处. for update 经常用,而for updade of 却不常用,现在将这两个作一个区分a.    select * from test for update 锁定表的所有行,只能读不能写 b.  select * from test where i_d = 1 for update 只锁定i_d=1的行,对于其他的表的其他行却不锁定下面再创建一个表create table t (dept_id  varchar(10),dept_name varchar2(50));c.  select * from test  a join t on a.i_d=t.dept_id for update;  这样则会锁定两张表的所有数据d.  select * from test  a join t on a.i_d=t.dept_id where a.i_d=1 for update;  这样则会锁定满足条件的数据e.  select * from test  a join t on a.i_d=t.dept_id where a.i_d=1 for update of a.i_d; 注意区分 d与e,e只分锁定表test中满足条件的数据行,而不会锁定表t中的数据,因为之前在procedure中作一个update,而需要update的数据需要关联查询,所以用了for update造成其他用户更新造成阻塞,所以才查到这段资料. for update of 是一个行级锁,这个行级锁,开始于一个cursor 打开时,而终止于事务的commit或rollback,而并非cursor的close.如果有两个cursor对于表的同一行记录同时进行update,实际上只有一个cursor在执行,而另外一个一直在等待,直至另一个完成,它自己再执行.如果第一个cursor不能被很好的处理,第二个cursor也不主动释放资源,则死锁就此产生.执行如下代码就会死锁(在两个command window中执行)declare
 cursor cur_test
   is
   select name,code from test where i_d=1 for update of name;
begin   for rec in cur_test loop
      update test set name="TTTT1" where current of cur_test;
 end loop;
end;
/declare
 cursor cur_test
   is
   select name,code from test where i_d=1 for update of name;
begin   for rec in cur_test loop
      update test set name="TTTT2" where current of cur_test;
 end loop;
end;
/注意两个pl/sql块中没有commit;为了解决这个死锁问题,要么就是第一个块释放资源,要么就是第二块主动放弃.第一次释放资源很简单,那就执行commit或rollback;而让第二块主动放弃,在for update 后加no wait;这样就会报ORA-00054 [resource busy and acquire with NOWAIT specified 的错误,这样就没有死锁了.《精通Oracle10g PL/SQL编程》 是本Oracle入门的好书关于如何删除Oracle数据库中重复记录相关资讯      Oracle教程 
  • Oracle中纯数字的varchar2类型和  (07/29/2015 07:20:43)
  • Oracle教程:Oracle中查看DBLink密  (07/29/2015 07:16:55)
  • [Oracle] SQL*Loader 详细使用教程  (08/11/2013 21:30:36)
  • Oracle教程:Oracle中kill死锁进程  (07/29/2015 07:18:28)
  • Oracle教程:ORA-25153 临时表空间  (07/29/2015 07:13:37)
  • Oracle教程之管理安全和资源  (04/08/2013 11:39:32)
本文评论 查看全部评论 (0)
表情: 姓名: 字数