楼主: berbang

[精华] 关于cursor中的for update关键字

[复制链接]
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
11#
发表于 2003-4-25 16:34 | 只看该作者
谢谢app_kwan!

使用道具 举报

回复
论坛徽章:
4
12#
发表于 2003-4-29 04:40 | 只看该作者
刚才测试了一下,发现有一个问题:
for update of 后面随便写表中的哪个字段都可以,并不一定是要被更新的字段,但这其中会有些不同吧?


1>。在FOR UPDATE OF[/COLOR]之后所枚举的字段(column),不一定是要被更新的字段。 -- 这个Hendytai 己证明了。

2>。此外,要么不用NOWAIT[/COLOR];若用NOWAIT[/COLOR],就必需最少枚举一个任意字段(column)。否则PLS-00404出现。例子,

请教:关于FOR UPDATE OF .. NOWAIT

注:这限制在Version 9i 应会除去。

3>。但是,有些朋友总觉得在FOR UPDATE OF[/COLOR]之后所枚举的字段(column)是多余的,
所以还觉不爽 -- 通常有这感觉的,大多是爱完美,那也是好的。

而解决的方法就是直接用ROWID替代WHERE CURRENT OF [I]YOUR_CURSOR_NAME[/I][/COLOR]语句。
例子如下,

[php]
declare
    -- query emp.name
    cursor cur_emp
        is
    select a.deptno,
           a.dname,
           a.rowid,
           b.rowid rowid_1
      from dept a, emp b
     where empno = 7369
       and a.deptno = b.deptno
       for update nowait;

    -- local variables
    v_deptno dept.deptno%type;
    v_dname dept.dname%type;
    v_rowid rowid;
    v_rowid_1 rowid;

begin
    open cur_emp;
    loop
    fetch cur_emp into v_deptno, v_dname, v_rowid, v_rowid_1;
    exit when cur_emp%notfound;

       update dept
          set dname = 'abc'
        where rowid = v_rowid;

       update emp
          set ename = 'frank'
        where rowid = v_rowid_1;

    end loop;
    close cur_emp;
    commit;
exception
    when others then
       rollback;
       raise;
end;
[/php]


由此,我自己的FOR UPDATE习惯是,
  • NOWAIT[/COLOR]定然跟FOR UPDATE之后。
  • 直接用ROWID替代WHERE CURRENT OF [I]YOUR_CURSOR_NAME[/I][/COLOR]语句,
    尤其在相对繁习的程序里头。
  • COMMIT必需存在程序结尾。以防死锁成形。
  • EXCEPTION里的ROLLBACK是最基本的需要。


希望这对大家基本认识FOR UPDATE有帮助。







- app

使用道具 举报

回复
论坛徽章:
3
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44
13#
 楼主| 发表于 2003-4-29 12:00 | 只看该作者
多谢App_Kwan!!我再研究一下,有问题再请教。

使用道具 举报

回复
论坛徽章:
1
2010新春纪念徽章
日期:2010-03-01 11:19:07
14#
发表于 2003-8-22 12:25 | 只看该作者
用where current of cur_emp和rowid速度哪个快?

使用道具 举报

回复
论坛徽章:
1
15#
发表于 2003-9-7 21:48 | 只看该作者
呵呵,这个不用讨论了。Oracle是行锁,没法到字段,那里那样写只是为了显式表示需要更新的字段,换成那个对效果没有任何区别。

使用道具 举报

回复
论坛徽章:
0
16#
发表于 2003-9-8 11:53 | 只看该作者
一般直接用FOR UPDATE, 后面什么也不用写就行

使用道具 举报

回复
论坛徽章:
0
17#
发表于 2004-3-14 17:15 | 只看该作者
那么就时说,显示加得字段名时为了描述用的了!!

使用道具 举报

回复
论坛徽章:
0
18#
发表于 2004-3-16 13:15 | 只看该作者

我认为:

1、语法:
         select ...
                  from ...
                  where ...
                  for update (of ...) nowait;  --of...是可选的
2、for update 后跟of column1, 作用是当select from 多个表时, 只锁住column1所在的表。
3、关于锁,可以声明一个exception
     -- Resource Busy
      e_res_busy exception;
      pragma exception_init(e_res_busy, -54);
      然后在exception处理中捕捉此exception, 再作相应处理

使用道具 举报

回复
论坛徽章:
0
19#
发表于 2004-8-10 14:45 | 只看该作者
说得好,有道理

使用道具 举报

回复
论坛徽章:
1
ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
20#
发表于 2004-8-10 21:39 | 只看该作者
受用

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表