阅读目录:存储过程的异常处理

    continue

    exit

    关于错误编号和SQLSTATE码

    使用3个处理程序

    忽略某一异常的处理

Q:何为异常?

A:程序在执行过程中有可能出错,运行时错误叫做异常。

默认情况下,当存储过程运行出错时,过程会立即终止,并打印系统错误消息。

实验环境:

mysql> use TENNIS
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A Database changed
mysql> show tables;
+-------------------+
| Tables_in_TENNIS |
+-------------------+
| COMMITTEE_MEMBERS |
| MATCHES |
| PENALTIES |
| PLAYERS |
| TEAMS |
+-------------------+
rows in set (0.00 sec)

因为前面的实验多数用此数据库,库表结构就不再赘述了。

例:创建过程,插入一个重复的2号球队

mysql> delimiter $$
mysql> create procedure duplicate_teams(
->   out p_processed smallint)
-> begin
->   set p_processed=;
->   insert into TEAMS values(,,'third');
->   set p_processed=;
-> end $$
mysql> delimiter ;
mysql> call duplicate_teams(@processed);
ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY'
mysql> select @processed;
+------------+
| @processed |
+------------+
| NULL |
+------------+

解析:客户端调用存储过程,运行出错,打印错误信息,过程被终止,没有输出。

一、定义异常处理:

DECLARE ... HANDLER语句:

  通过条件的定义和处理,可以在定义过程中,针对可能遇到的问题,做出相应的处理步骤。(也就是定义一个异常处理程序,指定当过程某条语句出错时,相应的采取什么操作)

DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement handler_action:
CONTINUE
| EXIT condition_value:
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION

注意:declare……handler语句必须出现在变量或条件声明的后面。

  当某个错误(condition_value)发生时--->执行指定的语句(statement--记录错误信息),执行完之后再决定如何操作(handler_action)。

  1、handler_action

    continue:继续执行当前的程序(接着执行出错的SQL的下一条语句);

    exit:当前程序终止(退出当前declare所在的begin end);

  目前还不支持undo功能。

  2、statement

    可以是单条语句或复合语句。

  3、condition_value指明handler被何种条件触发;如果条件被触发,却没有handler被声明用于处理该条件,程序的进行将取决于条件类型。

二、单个异常处理程序

  在输出参数中包含出错消息的SQLSTATE码。

例1:创建过程,插入一个重复的2号球队;continue

mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake1(
->   OUT error VARCHAR())
-> BEGIN
->   DECLARE CONTINUE HANDLER FOR SQLSTATE ''
->   SET error = ''; #用来记录错误发生时的一些信息
->
->   select error;
->   SET error = '';
->   select error;
-> INSERT INTO TEAMS VALUES(,,'third'); #会出错的语句
-> SET error = '';
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake1(@a);
+-------+
| error |
+-------+
| NULL |
+-------+ +-------+
| error |
+-------+
| |
+-------+ mysql> select @a;
+-------+
| @a |
+-------+
| |
+-------+

实验示例解析:

  begin end块里,定义declare……handler语句用来捕获错误(待命ing),select、set、select顺序执行,insert语句出错,SQLSTATE码23000,捕获,进行异常处理(赋值记录),结束后会继续执行出错的insert语句的下一条语句……

例2:创建过程,插入一个重复的2号球队;exit

mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake2(
->   OUT error VARCHAR())
-> BEGIN
->   DECLARE EXIT HANDLER FOR SQLSTATE ''
->   SET error = '';
->
->   select error;
->   SET error = '';
->   select error;
->   INSERT INTO TEAMS VALUES(,,'third');
->   SET error = '';
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake2(@a);
+-------+
| error |
+-------+
| NULL |
+-------+ +-------+
| error |
+-------+
| |
+-------+ mysql> select @a;
+-------+
| @a |
+-------+
| |
+-------+

与例1唯一不同的是:handler_action选择的是exit,表明在异常处理结束后不会继续执行错误语句后面的语句,直接退出begin end语句块。

三、多个异常处理程序

  可以在一个过程中定义多个异常处理程序,针对不同的错误进行不同的处理。

例1:

mysql> INSERT INTO TEAMS VALUES(,,'third',);
ERROR (21S01): Column count doesn't match value count at row 1 mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake3(
->   OUT error VARCHAR())
-> BEGIN
->   DECLARE CONTINUE HANDLER FOR SQLSTATE ''
->   SET error = '';
->
->   DECLARE CONTINUE HANDLER FOR SQLSTATE '21S01'
->   SET error = '21S01';
->
->   INSERT INTO TEAMS VALUES(,,'third',); #错误语句
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake3(@error);
mysql> select @error;
+--------+
| @error |
+--------+
| 21S01 |
+--------+

解析:

  如果SQLSTATE码是23000,异常处理执行SET error = '23000';

  如果SQLSTATE码是21S01,异常处理执行SET error = '21S01';

当然,异常处理,可以是自定义,一般都是上述方式的错误信息记录。

示例3中的异常处理程序也可以使用错误编号

例如:

DECLARE CONTINUE HANDLER FOR
SET error = ''; DECLARE CONTINUE HANDLER FOR
SET error = '21S01';

关于错误编号和SQLSTATE码:

  每个MySQL错误都有一个唯一的数字错误编号(mysql_error_code),每个错误又对应一个5字符的SQLSTATE码(ANSI SQL 采用)。

SQLSTATE码对应的处理程序:

  1、SQLWARNING处理程序:以‘01’开头的所有sqlstate码与之对应;

  2、NOT FOUND处理程序:以‘02’开头的所有sqlstate码与之对应;

  3、SQLEXCEPTION处理程序:不以‘01’或‘02’开头的所有sqlstate码,也就是所有未被SQLWARNING或NOT FOUND捕获的SQLSTATE(常遇到的MySQL错误就是非‘01’、‘02’开头的)

注意:‘01’、‘02’开头和‘1’、‘2’开头是有区别的,是不一样的错误sqlsate码。

当不想为每个错误都定义一个处理程序时,可以使用3个处理程序

  e.g:DECLARE CONTINUE HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION

mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake4(
->   OUT error VARCHAR())
-> BEGIN
->   DECLARE CONTINUE HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION
->   SET error = 'xxxxx';
->
->   INSERT INTO teams VALUES(,,'third');
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake4(@a);
mysql> select @a;
+-------+
| @a |
+-------+
| xxxxx |
+-------+

如果是在定义处理程序时,想忽略某一个条件

e.g:DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;

也就是说,当遇到SQLWARNING的问题时,进行的异常处理是begin end块,因为里面什么都没有,就类同于直接忽略。

四、异常处理的命名

  为了提高可读性,可以给某个sqlstate代码或mysql错误代码一个名字,并且在后面的异常处理程序中使用这个名字。

DECLARE condition_name CONDITION FOR condition_value

condition_value:
mysql_error_code
|SQLSTATE [VALUE] sqlstate_value

1、未命名的基本格式:

BEGIN
  DECLARE CONTINUE HANDLER FOR
-- body of handler
END;

2、有命名的基本格式:

BEGIN
  DECLARE no_such_table CONDITION FOR ;
  DECLARE CONTINUE HANDLER FOR no_such_table
-- body of handler
END;
mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake5(
->   OUT error VARCHAR())
-> BEGIN
->   DECLARE non_unique CONDITION FOR SQLSTATE '';
->   DECLARE CONTINUE HANDLER FOR non_unique
->   begin
->     SET error = '';
->     select error;
->   end;
->
->   INSERT INTO TEAMS VALUES(,,'third'); #会出错语句
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake5(@error);
+-------+
| error |
+-------+
| |
+-------+

五、异常传播

  在嵌套块的情况下,内部块中发生异常了,首先由本块的异常处理程序来处理,如果本块没有处理,则由外部块的异常处理程序来处理。

mysql> DELIMITER $$
mysql> CREATE PROCEDURE small_mistake6()
-> BEGIN
->   DECLARE CONTINUE HANDLER FOR SQLSTATE ''
->   SET @processed = ;
->
->   BEGIN
->     DECLARE CONTINUE HANDLER FOR SQLSTATE ''
->     SET @processed = ;
->     INSERT INTO TEAMS VALUES(,,'third');
->     set @test=;
-> END;
-> END$$
mysql> DELIMITER ;
mysql> call small_mistake6;
mysql> select @processed,@test;
+------------+--------+
| @processed | @test |
+------------+--------+
| | |
+------------+--------+

解析:@processed=100说明内部块里的异常传播到了外部块,交由外部块的异常处理程序进行的处理。

墙裂建议:

  当有多层begin end的时候,每层都应该有自己完善的异常处理,做到:自己的异常,自己这层去处理。

MySQL存储过程的异常处理的更多相关文章

  1. mysql存储过程之异常处理篇

    mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现 语法如下: DECLARE handler_type HANDLER FOR condition_value[, ...

  2. 详解MySQL存储过程的“异常处理”

    阅读目录:存储过程的异常处理 定义异常处理 单一异常处理程序 continue exit 多个异常处理程序 关于错误编号和SQLSTATE码 使用3个处理程序 忽略某一异常的处理 异常处理的命名 异常 ...

  3. MySQL 存储过程的异常处理

    mysql> mysql> delimiter $$ mysql> mysql> CREATE PROCEDURE myProc     ->     (p_first_ ...

  4. MySQL存储过程学习笔记

    MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣.MySQL 5.0终于开始支持存储过程了. MySQL的关键字大小写通用.该学习笔记对关键字使用大写:变量名,表名使用小写. ...

  5. MYSQL 存储过程 多表更新异常捕捉和异常处理方式

    今天在做MYSQL 存储过程 多表更新的功能   多表更新时候注意事项 1.首先是确保多表更新能够一次执行,途中没有哪个表的sql语句错误 2.上线后修改表结构及字段,请注意检查是否影响mysql 过 ...

  6. MySQL存储过程(转)

    一.MySQL 创建存储过程 "pr_add" 是个简单的 MySQL 存储过程,这个存储过程有两个 int 类型的输入参数 "a"."b" ...

  7. MySql存储过程

    MySQL 存储过程 ```sql CREATE PROCEDURE myprocedure (IN para01 INTEGER) BEGIN DECLARE var01 CHAR(10); IF ...

  8. mysql存储过程之游标遍历数据表

    原文:mysql存储过程之游标遍历数据表 今天写一个mysql存储过程,根据自己的需求要遍历一个数据表,因为对存储过程用的不多,语法不甚熟悉,加之存储过程没有调试环境,花了不少时间才慢慢弄好,故留个痕 ...

  9. MySQL 存储过程 经常使用语法

    MySQL 存储过程是从 MySQL 5.0 開始添加的新功能.存储过程的长处有一箩筐.只是最基本的还是运行效率和SQL 代码封装.特别是 SQL 代码封装功能,假设没有存储过程,在外部程序訪问数据库 ...

随机推荐

  1. Spring Boot 自定义属性 以及 乱码问题

    自定义属性 使用随机数及自定义配置类 中文乱码问题 1添加配置 2设置文件类型 1IDEA 2eclipse 自定义属性 application.properties提供自定义属性的支持,这样我们就可 ...

  2. AutoCAD 导入 Altium Designer 10 教程

    http://www.geek-workshop.com/thread-5478-1-1.html

  3. php 根据身份证获取出身地址

    <?php /**根据身份证算出地址****/ class addr{ /**获取省***/ public function get_shenfen($id){ //截取前两位数 $index ...

  4. SpringMVC深度探险(三) —— DispatcherServlet与初始化主线

    在上一篇文章中,我们给出了构成SpringMVC应用程序的三要素以及三要素的设计过程.让我们来归纳一下整个设计过程中的一些要点: SpringMVC将Http处理流程抽象为一个又一个处理单元 Spri ...

  5. 安装JDK时提示 IllegalArgumentException:Invalid characters in hostname的解决方法

    今天在windows7_x64上安装JDK的时候提示IllegalArgumentException:Invalid characters in hostname, 解决方法: 1.打开[控制面板\系 ...

  6. 【转】腾讯移动品质中心TMQ [腾讯 TMQ] 测试管理平台大比拼

    简介 测试管理平台是贯穿测试整个生命周期的工具集合,它主要解决的是测试过程中团队协作的问题,比如缺陷管理.用例管理.测试任务管理等. 目前市面上比较流行的测试管理工具有QC. Mantis. BugZ ...

  7. Sword pcre库使用

    #include <stdlib.h> #include <string.h> #include "regularhelper.h" #include &q ...

  8. ubuntu 挂载硬盘

    https://cndaqiang.github.io/2017/10/11/ubuntu-disk/ 查看硬盘 查看方法一 查看/dev下面的设备文件 ll -h /dev/sd* 通过sudo f ...

  9. 【转】【MySQL】Mysql模糊查询like提速优化

    在使用msyql进行模糊查询的时候,很自然的会用到like语句,通常情况下,在数据量小的时候,不容易看出查询的效率,但在数据量达到百万级,千万级的时候,查询的效率就很容易显现出来.这个时候查询的效率就 ...

  10. 新网站如何做SEO优化【转】

    “百度快照变慢了.百度收录问题.关键词掉了”,这是在卢松松留言本被经常问及的问题,新手站长往往会因此吃不下饭.睡不着觉,网站的推广是一个漫长的过程,“心急吃不了热豆腐”,不要整天想着一建站就有巨大的流 ...