`
walksing
  • 浏览: 211889 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现

阅读更多
mysql存储过程之异常处理篇
文章分类:数据库
mysql存储过程也提供了对异常处理的功能:通过定义HANDLER来完成异常声明的实现





语法如下:

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

Handlers类型:

1, EXIT: 发生错误时退出当前代码块(可能是子代码块或者main代码块)
2, CONTINUE: 发送错误时继续执行后续代码

condition_value:

condition_value支持标准的SQLSTATE定义;

SQLWARNING是对所有以01开头的SQLSTATE代码的速记

NOT FOUND是对所有以02开头的SQLSTATE代码的速记

SQLEXCEPTION是对所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE代码的速记

除了SQLSTATE值,MySQL错误代码也被支持


但是对于mysql而言,优先级如下:
MySQL Error code > SQLSTATE code > 命名条件







使用SQLSTATE还是MySQL Error Code?

1,SALSTATE是标准,貌似会更portable,但是实际上MySQL、DB2、Oracle等等的存储程序语法大相径庭,所以portable的优势不存在
2,MySQL error code与SQLSTATE并不是一一对应的,比如很多MySQL error code都映射到同一SQLSTATE code(HY000)

当MySQL客户端碰到错误时,它会报告MySQL error code和相关的SQLSATE code:

mysql > CALL nosuch_sp();
ERROR 1305 (42000): PROCEDURE sqltune.nosuch_sp does not exist

具体的sqlsdate和mysql error code的对应可以在http://dev.mysql.com/doc/的MySQL reference manual的附录B找到完整的最新的error codes



condition_name:命名条件

MySQL error code或者SQLSTATE code的可读性太差,所以引入了命名条件:

语法:

Java代码
1.DECLARE condition_name CONDITION FOR condition_value  
2. 
3.condition_value:  
4.    SQLSTATE [VALUE] sqlstate_value  
5.  | mysql_error_code 
DECLARE condition_name CONDITION FOR condition_value

condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code 使用:


Java代码
1.# original  
2.DECLARE CONTINUE HANDLER FOR 1216 MySQL_statements;  
3. 
4.# changed  
5.DECLARE foreign_key_error CONDITION FOR 1216;  
6.DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements; 
# original
DECLARE CONTINUE HANDLER FOR 1216 MySQL_statements;

# changed
DECLARE foreign_key_error CONDITION FOR 1216;
DECLARE CONTINUE HANDLER FOR foreign_key_error MySQL_statements;  用condition_name为错误代码起了个别名。



示例1:Duplicate entry Handler


Sql代码
1.CREATE PROCEDURE sp_add_location  
2.    (in_location    VARCHAR(30),  
3.     in_address1    VARCHAR(30),  
4.     in_address2    VARCHAR(30),  
5.     zipcode        VARCHAR(10),  
6.     OUT out_status VARCHAR(30))  
7.BEGIN 
8.    DECLARE CONTINUE HANDLER  
9.        FOR 1062  
10.        SET out_status='Duplicate Entry';  
11. 
12.    SET out_status='OK';  
13.    INSERT INTO locations  
14.        (location,address1,address2,zipcode)  
15.    VALUES 
16.        (in_location,in_address1,in_address2,zipcode);  
17.END; 
CREATE PROCEDURE sp_add_location
    (in_location    VARCHAR(30),
     in_address1    VARCHAR(30),
     in_address2    VARCHAR(30),
     zipcode        VARCHAR(10),
     OUT out_status VARCHAR(30))
BEGIN
    DECLARE CONTINUE HANDLER
        FOR 1062
        SET out_status='Duplicate Entry';

    SET out_status='OK';
    INSERT INTO locations
        (location,address1,address2,zipcode)
    VALUES
        (in_location,in_address1,in_address2,zipcode);
END;


示例2: Last Row Handler




Sql代码
1.CREATE PROCEDURE sp_not_found()  
2.    READS SQL DATA  
3.BEGIN 
4.    DECLARE l_last_row INT DEFAULT 0;  
5.    DECLARE l_dept_id INT:  
6.    DECLARE c_dept CURSOR FOR 
7.        SELECT department_id FROM departments;  
8.    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row=1;  
9. 
10.    OPEN c_dept;  
11.    dept_cursor: LOOP  
12.        FETCH c_dept INTO l_dept_id;  
13.        IF (l_last_row=1) THEN 
14.            LEAVE dept_cursor;  
15.        END IF;  
16.    END LOOP dept_cursor;  
17.    CLOSE c_dept;  
18.END; 
CREATE PROCEDURE sp_not_found()
    READS SQL DATA
BEGIN
    DECLARE l_last_row INT DEFAULT 0;
    DECLARE l_dept_id INT:
    DECLARE c_dept CURSOR FOR
        SELECT department_id FROM departments;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET l_last_row=1;

    OPEN c_dept;
    dept_cursor: LOOP
        FETCH c_dept INTO l_dept_id;
        IF (l_last_row=1) THEN
            LEAVE dept_cursor;
        END IF;
    END LOOP dept_cursor;
    CLOSE c_dept;
END;


综合示例:

Sql代码
1.CREATE PROCEDURE sp_add_department  
2.    (p_department_name     VARCHAR(30),  
3.     p_manager_surname     VARCHAR(30),  
4.     p_manager_firstname   VARCHAR(30),  
5.     p_location            VARCHAR(30),  
6.     OUT p_sqlcode         INT,  
7.     OUT p_status_message  VARCHAR(100))  
8.BEGIN 
9. 
10.    /* START Declare Conditions */  
11. 
12.    DECLARE duplicate_key CONDITION FOR 1062;  
13.    DECLARE foreign_key_violated CONDITION FOR 1216;  
14. 
15.    /* END Declare COnditions */  
16. 
17.    /* START Declare variables and cursors */  
18. 
19.    DECLARE l_manager_id INT;  
20.    DECLARE csr_mgr_id CURSOR FOR 
21.        SELECT employee_id FROM employees  
22.        WHERE surname=UPPER(p_manager_surname)  
23.        AND firstname=UPPER(p_manager_firstname);  
24. 
25.    /* END Declare variables and cursors */  
26. 
27.    /* START Declare Exception Handlers */  
28. 
29.    DECLARE CONTINUE HANDLER FOR duplicate_key  
30.    BEGIN 
31.        SET p_sqlcode=1052;  
32.        SET p_status_message='Duplicate key error';  
33.    END;  
34. 
35.    DECLARE CONTINUE HANDLER FOR foreign_key_violated  
36.    BEGIN 
37.        SET p_sqlcode=1216;  
38.        SET p_status_message='Foreign key violated';  
39.    END;  
40. 
41.    DECLARE CONTINUE HANDLER FOR NOT FOUND  
42.    BEGIN 
43.        SET p_sqlcode=1329;  
44.        SET p_status_message='No record found';  
45.    END;  
46. 
47.    /* END Declare Exception Handlers */  
48. 
49.    /* START Execution */  
50. 
51.    SET p_sqlcode=0;  
52.    OPEN csr_mgr_id;  
53.    FETCH csr_mgr_id INTO l_manager_id;  
54. 
55.    IF p_sqlcode<>0 THEN     /* Failed to get manager id */  
56.        SET p_status_message=CONCAT(p_status_message,' when fetching manager id');  
57.    ELSE                     /* Got manager id, we can try and insert */  
58.        INSERT INTO departments (department_name, manager_id, location)  
59.        VALUES(UPPER(p_department_name), l_manager_id, UPPER(p_location));  
60.        IF p_sqlcode<>0 THEN /* Failed to insert new department */  
61.            SET p_status_message=CONCAT(p_status_message, ' when inserting new department');  
62.        END IF;  
63.    END IF;  
64. 
65.    CLOSE csr_mgr_id;  
66. 
67.    /* END Execution */  
68. 
69.END  
分享到:
评论

相关推荐

    MySQL存储过程中一些基本的异常处理教程

    Mysql 支持异常处理,通过定义 CONTINUE/EXIT 异常处理的 HANDLER 来捕获 SQLWARNING/NOT FOUND/SQLEXCEPTION (警告 / 无数据 / 其他异常)。其中, FOR 后面可以改为 SQLWARNING, NOT FOUND, SQLEXCEPTION 来指示...

    mysql存储过程之错误处理实例详解

    其中mysql提供了一种简单的方法来定义处理从一般条件(如警告或异常)到特定条件(例如特定错误代码)的处理程序。完事我们来使用DECLARE HANDLER语句来尝试声明一个处理程序,先来看语法: DECLARE action HANDLER FOR...

    mysql存储过程中的异常处理解析

    定义异常捕获类型及处理方法:  DECLARE handler_action HANDLER FOR condition_value [, condition_value] ... statement handler_action: CONTINUE | EXIT | UNDO condition_value: mysql_error_code...

    MySQL定义异常和异常处理详解

    定义异常是事先定义程序执行过程中遇到的问题,异常处理定义了在遇到问题时对应当采取的处理方式,并且保证存储过程或者函数在遇到错误时或者警告时能够继续执行。  1 异常定义  1.1 语法  DECLARE condition_...

    MySQL 5.1官方简体中文参考手册

    5.7.3. MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码哈希处理 5.8...

    MySQL 5.1中文手冊

    5.7.3. MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码哈希处理 5.8...

    MySQL 5.1参考手册

    MySQL 5.1参考手册.chm 前言 1. 一般信息 1.1. 关于本手册 1.2. 本手册采用的惯例 1.3. MySQL AB概述 1.4. MySQL数据库管理系统概述 1.4.1. MySQL的历史 1.4.2. MySQL的的主要特性 1.4.3. MySQL稳定性 1.4.4. MySQL...

    MySQL 5.1参考手册中文版

    5.7.3. MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码哈希...

    MySQL 5.1参考手册 (中文版)

    5.7.3. MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码哈希处理 5.8...

    mysql5.1中文手册

    MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码...

    MYSQL中文手册

    5.7.3. MySQL提供的权限 5.7.4. 与MySQL服务器连接 5.7.5. 访问控制, 阶段1:连接核实 5.7.6. 访问控制, 阶段2:请求核实 5.7.7. 权限更改何时生效 5.7.8. 拒绝访问错误的原因 5.7.9. MySQL 4.1中的密码哈希...

    Mysql的游标的定义使用及关闭深入分析

    Mysql从5.0开始支持存储过程和trigger,给我们喜欢用mysql的朋友们更喜欢mysql的理由了,语法上和PL/SQL有差别,不过搞过编程的人都知道,语法不是问题,关键是思想,大致了解语法后,就从变量定义,循环,判断,...

    mysql官方中文参考手册

    MySQL 5.1参考手册 目录 前言 1. 一般信息 1.1. 关于本手册 1.2. 本手册采用的惯例 1.3. MySQL AB概述 1.4. MySQL数据库管理系统概述 1.4.1. MySQL的历史 1.4.2. MySQL的的主要特性 1.4.3. MySQL稳定性 1.4.4. ...

    MySQL5.1参考手册官方简体中文版

    MySQL 5.1参考手册 这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访问dev.mysql.com。 原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。 This translation was done by MySQL ...

    mysql数据库的基本操作语法

    但是MySQL可以通过多个modify的方式完成: alter table user modify tel varchar(15) default '02087654321' first, modify name varchar(20) after tel; 11、 删除指定字段 alter table user drop photo; 12、 ...

    MYSQL v4.1中文参考手册(CHM)

    6.1.7 MySQL 对保留字挑剔吗? 6.2 列类型 6.2.1 数字类型 6.2.2 Date 和 Time 类型 6.2.2.1 Y2K 问题和日期类型 6.2.2.2 DATETIME、DATE 和 TIMESTAMP 类型 6.2.2.3 TIME 类型 6.2.2.4 YEAR 类型 ...

    asp.net知识库

    存储过程中实现类似split功能(charindex) 通过查询系统表得到纵向的表结构 将数据库表中的数据生成Insert脚本的存储过程!!! 2分法-通用存储过程分页(top max模式)版本(性能相对之前的not in版本极大提高) 分页存储...

    ThinkPHP实现将SESSION存入MYSQL的方法

    本文以实例讲解了ThinkPHP实现将SESSION存入MYSQL的方法,所采用的运行环境是ThinkPHP3.1.2版 首先index.php中设置为: &lt;?php define('APP_DEBUG', true);//设置为调试模式 require '../ThinkPHP/ThinkPHP.php';...

    php网络开发完全手册

    10.2.4 异常处理函数设置set_exception 10.2.4 _handler 157 10.2.5 完整的异常信息 158 10.3 扩展的异常处理类 160 10.4 异常的传递与重掷 163 10.5 小结 165 第11章 PHP与表单 166 11.1 HTML表单简介 166 11.1.1 ...

Global site tag (gtag.js) - Google Analytics