视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
关于Oracle中update
2020-11-09 12:07:28 责编:小采
文档


前几天用到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 的错误,这样就没有死锁了.

下载本文
显示全文
专题