免费注册 查看新帖 |

Chinaunix

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

400上建的存储过程不能用事务控制? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-24 17:31 |只看该作者 |倒序浏览
为什么一加事务控制就 CPF83D0 出错?

  看IBM的提示
Cause . . . . . :   The COMMIT, ROLLBACK or ENDCMTCTL commitment operation   
  could not be completed for commitment definition &1 due to one of the      
  following reasons:                                                         
    -- A trigger program is running in the activation group related to this  
  commitment definition.                                                     
    -- A stored procedure is running in the activation group related to this
  commitment definition.     

     知道的人给个明白点的解释

论坛徽章:
0
2 [报告]
发表于 2007-01-24 20:49 |只看该作者
从错误信息来看,是否是因为没有设置事务控制交易属性造成出错的原因?!

一般在默认情况下,定义Store Procedure的时候,交易的定义是由当前作业的交易属性决定的,默认为*NONE,也就是所有的交易都以立即提交的方式处理,互相之间没有关联关系。在SQL Stored Procedure的执行过程中遇到的错误如果不进行处理,存储过程会异常终止, 并把SQLCODE提交到调用作业。

根据定义Stored Procedure方式不同,设置交易定义的方法也有所不同:

1. 在定义Stored Procedure时利用SET OPTION COMMIT参数 (** )
CREATE PROCEDURE QGPL/P1()
LANGUAGE SQL
SET OPTION COMMIT=*CHG
BEGIN
SQL_CLAUSE;
END;

2. 如果在STRSQL里执行CREATE PROCEDURE脚本
STRSQL COMMIT(*CHG)

3. 如果在RUNSQLSTM里执行CREATE PROCEDURE脚本
RUNSQLSTM SRCFILE(QSQLSRC) SRCMBR(MYPROC) COMMIT(*CHG) NAMING(*SQL)

4. 如果在Operation Navigator SQL中执行CREATE PROCEDURE脚本
/* run a set transaction statement before the create procedures */
set transaction isolation level chg;

/* issue the create procedure statements */
Create Procedure SQLSQL...;

/* commit the procedure(s) */
commit;

论坛徽章:
0
3 [报告]
发表于 2007-01-25 11:07 |只看该作者
strsql环境下

SET TRANSACTION ISOLATION LEVEL CHG

的执行结果

Message . . . . :   SQL statement cannot be run.                           
Cause . . . . . :   The statement cannot be run in the current application  
  state. A SET TRANSACTION or DISCONNECT statement was encountered and a   
  connection is not at a commit boundary.                                   
Recovery  . . . :   Issue a COMMIT or ROLLBACK. Try the request again.      

我是直接写好了一个CLP后,用一个SQLRPG把CREATE PROCEDURE xxxDTA/xxxXGC ......写好直接执行的。

strsql 环境下 F13改那个 Commitment control . . . . . .   *chg  可以达到效果吗?

   现在调那个存储过程不报错了,直接给我返回空,什么也没做。

论坛徽章:
0
4 [报告]
发表于 2007-01-25 11:21 |只看该作者
你可以尝试多种方式去处理。
同时,可以使用错误处理来控制。

DB2/400提供了以下4种错误处理方法:
1、condition和handler声明
2、 signal和resignal
3、使用SQL CODE和SQLSTATE
4、GET DIAGNOSTICS EXCEPTION

比如:3、使用SQL CODE和SQLSTATE
检查SQLCODE和SQLSTATE是数据库中用来判断SQL执行结果的常用手段

DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';

一旦定义上述两个变量以后,DB2/400在执行SQL语句后会自动更新这两个变量的取值

DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT ’00000’;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET retcode=SQLCODE;
DECLARE CONTINUE HANDLER FOR SQLWARNING SET retcode=SQLCODE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET retcode=SQLCODE;

论坛徽章:
0
5 [报告]
发表于 2007-01-25 11:36 |只看该作者
CLP程序

PGM     parm(*  *)
STRCMTCTL  LCKLVL(*CHG)                              
MONMSG     MSGID(CPF8351)                             
                                                      
CALL       PGM(xxxxxx) PARM(&xxxxx +
             &xxxxxx)                        
MONMSG     MSGID(CPF0000) EXEC(ROLLBACK)              
ENDCMTCTL                                             
ENDPGM            

创建存储过程的程序
SQLRPG
C/EXEC SQL                                                         
C+ CREATE PROCEDURE xxxx/xxxxx(IN xxuncd CHAR ( , IN xxaddr  
C+ CHAR ( 4), IN xxHYLB CHAR ( 4), OUT ppflg1                     
C+ CHAR ( 1)) LANGUAGE CL NOT DETERMINISTIC NO SQL EXTERNAL NAME   
C+ xxxx/xxxxxC PARAMETER STYLE GENERAL                          
C/END-EXEC

哪个地方需要补什么?  在400上直接执行CLP是没问题,但是从外面调存储就没法执行成功。

论坛徽章:
0
6 [报告]
发表于 2007-01-25 11:39 |只看该作者
补上:  CLP是去调用的一个RPG程序


希望轻舟能帮我找到问题所在

论坛徽章:
0
7 [报告]
发表于 2007-01-25 12:06 |只看该作者
你这个RPG中只是创建了一个存储过程,并没有执行此存储过程,而且在RPG中你并没有做commit或rollback

论坛徽章:
0
8 [报告]
发表于 2007-01-25 12:07 |只看该作者
CLP应该没什么问题,本身就是支持外部调用CALL RPG PARM(&XXX &XXX)。
个人觉得存储过程应该修改一下,Store Procedure使用交易处理主要体现在三个控制语句上:
COMMIT
ROLLBACK
SET TRANSACTION

你把这3项写到Store Procedure里面去,不要写在CLP里面。

例如:下面的实例实现的功能是对客户库中的所有客户记录,如果全部成功才提交,如果有一个失败则全部回滚整个交易。
你参照修改一下你的Store Procedure,然后运行一下,调试通过后,可将CLP中加入RUNSQLSTM调用Store Procedure语句。


  1. SET TRANSACTION LEVEL CHG; //改变交易处理的默认方式为CHG

  2. CREATE PROCEDURE CREDITP
  3. (IN i_perinc DECIMAL(3,2),
  4. INOUT o_numrec DECIMAL(5,0))
  5. LANGUAGE SQL
  6. BEGIN //Store Procedure实体
  7. DECLARE proc_cusnbr CHAR(5);
  8. DECLARE proc_cuscrd DECIMAL(11,2);
  9. DECLARE numrec DECIMAL(5,0);
  10. DECLARE at_end INT DEFAULT 0;
  11. DECLARE not_found
  12. CONDITION FOR '02000';
  13. DECLARE c1 CURSOR FOR
  14. SELECT cusnbr, cuscrd
  15. FROM ordapplib.customer;

  16. DECLARE CONTINUE HANDLER FOR not_found
  17. SET at_end = 1;
  18. SET numrec = 0;

  19. DECLARE EXIT HANDLER FOR SQLEXCEPTION
  20. ROLLBACK; ----//遇到任何SQL的异常,都默认执行ROLLBACK,回滚交易。

  21. OPEN c1;
  22. FETCH c1 INTO proc_cusnbr, proc_cuscrd;
  23. WHILE at_end = 0 DO
  24. SET proc_cuscrd = proc_cuscrd +(proc_cuscrd * i_perinc);
  25. UPDATE ordapplib.customer
  26. SET cuscrd = proc_cuscrd
  27. WHERE CURRENT OF c1;
  28. SET numrec = numrec + 1;
  29. FETCH c1 INTO proc_cusnbr, proc_cuscrd;
  30. END WHILE;
  31. SET o_numrec = numrec;
  32. CLOSE c1;

  33. COMMIT; //交易正常结束,提交数据库进行更新。

  34. END
复制代码

论坛徽章:
0
9 [报告]
发表于 2007-01-25 13:06 |只看该作者
我理解轻舟的意思。

  我目前的情况是内部很多RPG写好了的,都加了KCOMIT  COMIT  ROLBK  用一个公共的CLP来传参数进来。没法全去改成用SQL来写处理数据。
   我现在的问题是,为什么400上来执行加了事务的CLP+RPG的没问题,一用CREATE PROCEDURE把CLP声明成存储过程在外面怎么调后执行不了呢? 是不是CREATE PROCEDURE的时候要加
SET TRANSACTION LEVEL CHG 这句? 我在STRSQL环境下没法执行这条啊

[ 本帖最后由 sz_lixlx 于 2007-1-25 13:09 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2007-01-25 13:08 |只看该作者
我现在一调用就马上终止了,根据分析来,根本没有执行到RPG那里去
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP