Mysql的存储过程中的异常
2007-03-06 17:48
405 查看
以前看到一篇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的语法限制给去掉了!
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
# sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
此处的被屏蔽了,就变成都可以插入.把它改回去就行了!
要使用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的语法限制给去掉了!
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
# sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
此处的被屏蔽了,就变成都可以插入.把它改回去就行了!
相关文章推荐
- MySQL存储过程的异常处理方法
- MySQL存储过程中捕获异常的方法
- MySQL存储过程的“异常处理”
- mysql存储过程异常处理
- MySQL存储过程的异常处理方法
- MYSQL存储过程抓捕异常
- mysql存储过程中异常处理
- mysql存储过程中的异常处理
- mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入
- mysql存储过程异常处理
- [转]mysql 5.6 存储过程+事务+游标+错误异常抛出+日志写入
- MySQL存储过程的异常定义及处理
- Connection.prepareCall对Mysql存储过程产生异常的解决方法
- MySQL存储过程的“异常处理”
- 关于MySQL存储过程异常处理的一点心得
- mysql存储过程之异常处理篇
- MySQL存储过程中捕获异常的方法
- mysql的存储过程里面异常处理模块 为什么获取不了错误码?
- 【转】【MySql】mysql存储过程中的异常处理
- mysql存储过程中的异常处理解析