用php更新oracle表,关于Oracle中update

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

logo.gif

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值