以前看到一篇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;
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 ;
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>
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 > 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的语法限制给去掉了!

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