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的可读性太差,所以引入了命名条件:

语法:

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

使用:

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

condition_name为错误代码起了个别名。

示例1:Duplicate entry Handler

  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. SET out_status='OK';
  12. INSERT INTO locations
  13. (location,address1,address2,zipcode)
  14. VALUES
  15. (in_location,in_address1,in_address2,zipcode);
  16. END;

示例2: Last Row Handler

  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. OPEN c_dept;
  10. dept_cursor: LOOP
  11. FETCH c_dept INTO l_dept_id;
  12. IF (l_last_row=1) THEN
  13. LEAVE dept_cursor;
  14. END IF;
  15. END LOOP dept_cursor;
  16. CLOSE c_dept;
  17. END;

综合示例:

    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. /* START Declare Conditions */
    10. DECLARE duplicate_key CONDITION FOR 1062;
    11. DECLARE foreign_key_violated CONDITION FOR 1216;
    12. /* END Declare COnditions */
    13. /* START Declare variables and cursors */
    14. DECLARE l_manager_id INT;
    15. DECLARE csr_mgr_id CURSOR FOR
    16. SELECT employee_id FROM employees
    17. WHERE surname=UPPER(p_manager_surname)
    18. AND firstname=UPPER(p_manager_firstname);
    19. /* END Declare variables and cursors */
    20. /* START Declare Exception Handlers */
    21. DECLARE CONTINUE HANDLER FOR duplicate_key
    22. BEGIN
    23. SET p_sqlcode=1052;
    24. SET p_status_message='Duplicate key error';
    25. END;
    26. DECLARE CONTINUE HANDLER FOR foreign_key_violated
    27. BEGIN
    28. SET p_sqlcode=1216;
    29. SET p_status_message='Foreign key violated';
    30. END;
    31. DECLARE CONTINUE HANDLER FOR NOT FOUND
    32. BEGIN
    33. SET p_sqlcode=1329;
    34. SET p_status_message='No record found';
    35. END;
    36. /* END Declare Exception Handlers */
    37. /* START Execution */
    38. SET p_sqlcode=0;
    39. OPEN csr_mgr_id;
    40. FETCH csr_mgr_id INTO l_manager_id;
    41. IF p_sqlcode<>0 THEN     /* Failed to get manager id */
    42. SET p_status_message=CONCAT(p_status_message,' when fetching manager id');
    43. ELSE                     /* Got manager id, we can try and insert */
    44. INSERT INTO departments (department_name, manager_id, location)
    45. VALUES(UPPER(p_department_name), l_manager_id, UPPER(p_location));
    46. IF p_sqlcode<>0 THEN /* Failed to insert new department */
    47. SET p_status_message=CONCAT(p_status_message, ' when inserting new department');
    48. END IF;
    49. END IF;
    50. CLOSE csr_mgr_id;
    51. /* END Execution */
    52. END
    53. 原文:http://wwty.iteye.com/blog/698239

mysql存储过程之异常处理篇的更多相关文章

  1. mysql存储过程之事务篇

    mysql存储过程之事务篇 事务的四大特征: ACID:Atomic(原子性).Consistent(一致性).Isolated(独立性).Durable (持久性) MySQL的事务支持不是绑定在M ...

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

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

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

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

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

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

  5. MySQL存储过程学习笔记

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

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

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

  7. MySQL存储过程(转)

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

  8. MySql存储过程

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

  9. mysql存储过程编写-入门案例-遁地龙卷风

    (-1)写在前面 这篇文章只是简要的叙述了mysql存储过程编写的基本概念. 我使用的mysql版本是5.7.9-log. 参照<<深入浅出MySQL>>. (0) delim ...

随机推荐

  1. java,js,jstl,EL的简单交互

    EL全名Expression Language.EL提供了在JSP脚本编制元素范围外使用运行时表达式的功能. 脚本编制元素是指页面中能够用于在JSP文件中嵌入java代码的元素. JSP标准标记库(j ...

  2. python协程和yeild

    python多线程其实在操作系统级别是进程,因为在执行时,默认加了一个全局解释器锁(GIL),python的多线程,本质还是串行的,无法利用多核的优势:在java和C# 中,多线程是并发的,可以充分利 ...

  3. Genymotion关于【启动后player.exe已停止运行】解决方案总结

    1. 你硬盘空间不足,或是暂存区不够,请少执行一些程序或关掉一些p2p的程序,或是到控制面板卸载一些不必要的程序.最好的建议是定期进行硬盘清理,确保不浪费多余空间 ---以上来源(http://www ...

  4. PHP扩展编写、PHP扩展调试、VLD源码分析、基于嵌入式Embed SAPI实现opcode查看

    catalogue . 编译PHP源码 . 扩展结构.优缺点 . 使用PHP原生扩展框架wizard ext_skel编写扩展 . 编译安装VLD . Debug调试VLD . VLD源码分析 . 嵌 ...

  5. Linux Network Related Drive

    catalog . 通过套接字通信 . 网络实现的分层模型 . 网络命名空间 . 套接字缓冲区 . 网络访问层 . 网络层 . 传输层 . 应用层 . 内核内部的网络通信 1. 通过套接字通信 Lin ...

  6. js调用刷新

    _self.fireEvent('refresh');

  7. pack、unpack自制二进制“数据库”

    引言 pack.unpack函数,如果没有接触过socket,这个可能会比较陌生,这两个函数在socket交互的作用是组包,将数据装进一个二进制字符串,和对二进制字符串中的数据进行解包,这个里面有好多 ...

  8. Node.js使用Mongoose包操作MongoDB数据库

    1. 安装Mongoose npm install mongoose 2. 使用 2.1 创建连接 var mongoose = require('mongoose'); mongoose.conne ...

  9. windows下安装使用Composer记录

    一直以来都是直接下载类库文件放到项目中使用 Composer是一个PHP依赖管理工具,有了它,就可以对依赖的包进行统一管理,而且在项目中可以实现自动加载 安装和使用composer 下载并且运行 Co ...

  10. 基于UDP协议的程序设计

    使用UdpClient类进行编程 UdpClient类的使用方法 第一阶段 创建UdpClient实例 UdpClient udpClient = new UdpClient(); IPAddress ...