免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5020 | 回复: 6
打印 上一主题 下一主题

求助:游标中rollback引起游标关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-08-28 09:59 |只看该作者 |倒序浏览
程序段:
declare test_cur cursor with hold for
     select .... from A where ... order by ... with ur;

open test_cur;
while( 1 ){
    fecth test_cur into ......;
    判断SQLCODE

    begin_work();           /* 其实就是设置了一个标志 */
    SQL 操作,修改其他表或者游标所在表的数据。
   根据结果判断 commit or rollback。    /* 此处如果rollback 游标被关闭 */
}

异常状态:
如果游标中进行了SQL操作,根据结果判断并rollback时,
下一次fetch时,会提示 501 没有打开游标。从而报错退出。
------------------------------
疑问:
使用前参考的文章:http://searchdatabase.techtarget.com.cn/tips/365/2297365.shtml
之中有说到: 
10.DB2的游标打开后遇到commit和rollback默认是会关闭的。保持游标打开的方法是在定义游标时加上with hold选项
但是,我declare 游标时使用了with hold选项,为什么还会出现这个问题?

[ 本帖最后由 tangsuilx 于 2006-8-28 10:19 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-08-28 10:10 |只看该作者

额卖糕的

从vlife以前的回复中找到的答案:
无论是否使用with hold与否,rollback将释放session中的游标。commit只释放不带with hold的游标。
--------------------------------
救命啊。这些程序是从informix移植过来的。
难道让我将满足条件的记录全部读到一个结构数组里面,然后再从结构数组里面逐条取出处理么?
量很大的哈。。。。我死了。。。

论坛徽章:
0
3 [报告]
发表于 2006-08-28 11:01 |只看该作者
摘自《SQL Reference Volume 2》
declare Cursor WITH HOLD
   Maintains resources across multiple units of work.

(1)For units of work ending with COMMIT:
   - Open cursors defined WITH HOLD remain open.
   - All locks are released, except locks protecting the current cursor position of open WITH HOLD cursors.
   。。。

(2)For units of work ending with ROLLBACK:
   -All open cursors are closed.
   -All locks acquired during the unit of work are released.
   。。。

[ 本帖最后由 zjsharp 于 2006-8-28 11:02 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2006-08-28 11:13 |只看该作者
用临时表试一试看?

论坛徽章:
0
5 [报告]
发表于 2006-08-28 16:36 |只看该作者

这种方案是否可行

游标改用普通游标。
游标取出当前记录后,fork子进程。
主进程只管从游标取数。
子进程进行事务、处理、判断、修改状态、提交等等。
主进程等子进程的结束信号,然后取下一条记录。
程序段:
declare test_cur cursor with hold for
     select .... from A where ... order by ... with ur;

open test_cur;
while( 1 ){
    fecth test_cur into ......;
    判断SQLCODE

    pid = fork();

    if( pid == 0 ) {    /* 子进程干活 */
            sqledtin( &sqlca );
            setsid();
            signal( SIGHUP, SIG_IGN );

            db_disconn( G_mdb_name );
            begin_work();           /* 其实就是设置了一个标志 */
            SQL 操作,修改其他表或者游标所在表的数据。
        根据结果判断 commit or rollback。   
        db_disconn();
            exit();
    }

    /* 主进程等待子进程结束 */
}
close test_cur;

论坛徽章:
0
6 [报告]
发表于 2006-08-29 09:17 |只看该作者
如果是两个不同的事务的话,你用CLI来写比较方便

论坛徽章:
0
7 [报告]
发表于 2006-09-01 17:08 |只看该作者

用savepoint

在cursor内部设立一个savepoint, rollback时用
rollback to savepoint a;
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP