Mysql的存储过程中的异常

以前看到一篇Mysql的存储过程,觉得很简单:

要使用Mysql的存储过程,需要:
1、Mysql的版本在5.0以上,低版本的海不支持存储过程;
2、数据表应该是InnoDB的,其他格式的不支持事务;

做一个实验:创建两个表,在存储过程中向两个表插入数据,使向第一表的插入操作执行成功,向第二个表的操作执行失败。然后存储过程应rollback,回滚到最初状态:两个表的数据都是空的。

第一步,创建表两个数据表:

 

drop table  if exists test1;
create table test1(
    a   char(1)
)ENGINE=INNODB;

drop table  if exists test2;
create table test2(
    a   int
)ENGINE=INNODB;

 

 

这样,如果想第二个表插入一个字符型的数据,肯定会插入失败。

第二步,创建存储过程:

 

delimiter //
drop procedure  if exists sp_test//
create procedure sp_test(
)

begin
    DECLARE EXIT HANDLER FOR SQLException ROLLBACK;
    start transaction;
    insert into test1 values('a');
    insert into test2 values('a');
    commit;
end
//
delimiter ;

 

 

因为在存储过程中,语句间的分隔符号是“;”,那么在创建存储过程的时候,需要先声明分隔符号是其他的符号,以避免在存储过程创建的过程中被mysql解释执行,所以预先将分隔符号设置为“//”,存储过程创建成功后,再设置回来。

关于对delimiter的理解,做几个小的实验就知道了。

第三步,执行,看结果:

 

mysql> drop table  if exists test1;
Query OK, 0 rows affected (0.04 sec)

mysql> create table test1(
    ->     a   char(1)
    -> )ENGINE=INNODB;
Query OK, 0 rows affected (0.10 sec)

mysql>
mysql> drop table  if exists test2;
Query OK, 0 rows affected (0.04 sec)

mysql> create table test2(
    ->     a   int
    -> )ENGINE=INNODB;
Query OK, 0 rows affected (0.08 sec)

mysql>
mysql>
mysql> delimiter //
mysql> drop procedure  if exists sp_test//
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> create procedure sp_test(
    -> )
    ->
    -> begin
    ->     DECLARE EXIT HANDLER FOR SQLException ROLLBACK;
    ->     start transaction;
    ->     insert into test1 values('a');
    ->     insert into test2 values('a');
    ->     commit;
    -> end
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql>
mysql> select * from test1;
Empty set (0.01 sec)

mysql> select * from test2;
Empty set (0.00 sec)

mysql> call sp_test();
Query OK, 0 rows affected (0.03 sec)

mysql> select * from test1;
Empty set (0.00 sec)

mysql> select * from test2;
Empty set (0.00 sec)

mysql>


这里面mysql遇到SQLException后,回滚了整个事务。

接下来,可以修改存储过程中的语句,让第二个插入过程是可以正确执行的,再次执行存储过程,可以看到mysql会commit数据。 

执行中却发现我的结果不是这样!而是如下

 

mysql >  delimiter  //
mysql >  drop procedure sp_test //
ERROR  1305  ( 42000 ): PROCEDURE test.sp_test does not exist
mysql
>  create procedure sp_test(
    
->  )
    
->  begin
    
->  declare exit handler  for  sqlexception rollback;
    
->  start transaction;
    
->  insert into test1 values( ' a ' );
    
->  insert into test2 values( ' a ' );
    
->  commit;
    
->  end
    
->   //
Query OK,  0  rows affected ( 0.01  sec)

mysql
>  delimiter ;
mysql
>  call sp_test();
Query OK, 
0  rows affected,  1  warning ( 0.03  sec)

mysql
>  select  *  from test1;
+------+
|  a     |
+------+
|  a     |
+------+
1  row  in   set  ( 0.00  sec)

mysql
>  select  *  from test2;
+------+
|  a     |
+------+
|      0   |
+------+
1  row  in   set  ( 0.00  sec)

很是奇怪,呵呵!后来才发现原来我把MYSQL 的php.ini的语法限制给去掉了!

 

# sql - mode = " STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION "

 

此处的被屏蔽了,就变成都可以插入.把它改回去就行了!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值