Heim > Datenbank > MySQL-Tutorial > Hauptteil

关于Oracle中update

WBOY
Freigeben: 2016-06-07 17:00:49
Original
1505 Leute haben es durchsucht

前几天用到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,
code='007' where i_d='1';
commit;

这样可以成功

--方式2

update test set (name,code)=(
'zhurhyme2','007')
where i_d='1';

注意,这样是不行,update set 必须为子查询,所以需要将其改为 :

--方式3

update 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 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 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 的错误,这样就没有死锁了.

linux

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!