DB2存储过程的事务控制以及错误处理。

文章主要内容是:如何去控制存储过程中,出错了该如何去控制整个事务,以保证数据的完整性,以及和你的预期相吻合。(由于本人用DB2的时间不长,文中有什么不对的地方,请大家指点迷津。谢谢)

1:先准备一下测试的环境:表TAA和表TBB:

 

ExpandedBlockStart.gif 代码
CREATE   TABLE  TBB
 (ID  
INTEGER           NOT   NULL   GENERATED  BY   DEFAULT
    
AS   IDENTITY  (START  WITH   1 , INCREMENT  BY   1 , CACHE  20 , MINVALUE  1 , MAXVALUE  2147483647 , NO CYCLE, NO  ORDER ),
  C1  
VARCHAR ( 128 )     NOT   NULL
 )
  DATA CAPTURE NONE
  
IN  USERSPACE1;

ALTER   TABLE  TBB
  LOCKSIZE ROW
  APPEND 
OFF
  
NOT  VOLATILE;

CREATE   TABLE  TAA
 (ID  
INTEGER           NOT   NULL   GENERATED  BY   DEFAULT
    
AS   IDENTITY  (START  WITH   1 , INCREMENT  BY   1 , CACHE  20 , MINVALUE  1 , MAXVALUE  2147483647 , NO CYCLE, NO  ORDER ),
  C1  
VARCHAR ( 128 )     NOT   NULL
 )
  DATA CAPTURE NONE
  
IN  USERSPACE1;

ALTER   TABLE  TAA
  LOCKSIZE ROW
  APPEND 
OFF
  
NOT  VOLATILE;

 

 

错误产生原因:不能把null值插入c1字段。

2:下面来创建测试的存储过程,一般情况下,没用过存储过程的人都会这样写:

 

CREATE   PROCEDURE  TEST_ZHAOGW ( ) 
  
BEGIN
    
INSERT   INTO  TAA (C1)  VALUES  ( ' AAAAAAA ' );
    
INSERT   INTO  TBB (C1)  VALUES  ( null );
end ;

 

其结果是:控制台提示出错信息,并且TAA表有一条'AAAAAAA'的记录。而TBB表是空的。

很多人都认为存储过程会自动处理,在存储过程中,它如果出错了,会自动帮你回滚存储过程中所执行的事务。来看下下面一段话:

  SQL procedure body 是存储过程的主体。其核心是一个复合语句。复合语句由关键词 BEGIN 和 END 包围。这些语句可以是 ATOMIC 或 NOT ATOMIC 的。默认情况下,它们是 NOT ATOMIC 的。SQL Procedures 要求复合语句中的声明和可执行语句符合特定的顺序。

3:上面的一段话就很好解析为何刚才的存储过程执行的结果了。我们就根据这段话,修改一下存储过程:

 

CREATE   PROCEDURE  TEST_ZHAOGW ( ) 
  
BEGIN
P1: 
BEGIN  ATOMIC
    
INSERT   INTO  TAA (C1)  VALUES  ( ' AAAAAAA ' );
    
INSERT   INTO  TBB (C1)  VALUES  ( null );
END  P1;
end ;

 

这里的P1其实可以不要的,如开头的那行可以是“BEGIN ATOMIC”后面的那行可以是“END;”。如果我没理解错,这个P1应该是这个复合语句的名称吧。 

其结果是:控制台提示出错信息,并且TAA和TBB表是空的。(事务是整个复合语句块回滚了)。

4:下面,大家来看一下,存储过程中定义错误的处理方式:

ExpandedBlockStart.gif 代码
CREATE   PROCEDURE  TEST_ZHAOGW ( ) 
  
BEGIN
DECLARE     CONTINUE     HANDLER    FOR  SQLEXCEPTION
P1: 
BEGIN  ATOMIC
    
INSERT   INTO  TAA (C1)  VALUES  ( ' AAAAAAA ' );
    
INSERT   INTO  TBB (C1)  VALUES  ( null );
    
INSERT   INTO  TAA (C1)  VALUES  ( ' bbbbbbbbb ' );
END  P1;
end ;

 

从字面上去理解是:出错继续。

其结果是:控制台提示执行成功。但TAA表和TBB表都没有插入数据。

5:把BEGIN ATOMIC去掉看看什么结果(错误定义的处理方式):

 

ExpandedBlockStart.gif 代码
CREATE   PROCEDURE  TEST_ZHAOGW ( ) 
  
BEGIN
DECLARE     CONTINUE     HANDLER    FOR  SQLEXCEPTION

    
INSERT   INTO  TAA (C1)  VALUES  ( ' AAAAAAA ' );
    
INSERT   INTO  TBB (C1)  VALUES  ( null );
    
INSERT   INTO  TAA (C1)  VALUES  ( ' bbbbbbbbb ' );

end ;

 

其结果是:控制台提示执行成功。但TAA表插入了'AAAAAAA',TBB表插入了'bbbbbbbbb'

我想这个设置,是用在一个存储过程中,后面的业务与前面的业务没有任何关联的,大家的操作都是相互独立的时候用到的,如设置的定时修复数据的存储过程。

复合语句:我的理解是:复合语句里面(begin 和end 之间)的代码看成是一个sql语句。因此就有了:

 

ExpandedBlockStart.gif 代码
CREATE   PROCEDURE  TEST_ZHAOGW ( ) 
  
BEGIN
    
INSERT   INTO  TAA (C1)  VALUES  ( ' AAAAAAA ' );
P1:
BEGIN  ATOMIC
    
INSERT   INTO  TAA (C1)  VALUES  ( ' bbbbbbbbb ' );
    
INSERT   INTO  TBB (C1)  VALUES  ( null );
end  P1;
end ;

 

其结果是:控制台提示出错信息,并且TAA表有一条'AAAAAAA'的记录。而TBB表是空的。它只回滚了复合语句块里面的

操作,外面的整个存储过程的语句块还是默认的NOT ATOMIC来的。大家还有什么疑问可以自己继续测试下,有什么特殊的发现,可以分享一下。

下面提供一些参考资料,以便大家参考使用:

http://doc.chinaunix.net/db2/200812/207691.shtml

http://weiruan85.javaeye.com/blog/312478

转载于:https://www.cnblogs.com/kfarvid/archive/2010/06/12/1756903.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值