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代码  

DECLARE condition_name CONDITION FOR condition_value

condition_value:

SQLSTATE [VALUE] sqlstate_value

| mysql_error_code

DECLARE condition_name CONDITION FOR condition_value

condition_value:

SQLSTATE [VALUE] sqlstate_value

| mysql_error_code

使用:

Java代码  

# original

DECLARE CONTINUE HANDLER FOR1216MySQL_statements;

# changed

DECLARE foreign_key_error CONDITION FOR1216;

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代码  

CREATEPROCEDUREsp_add_location

(in_locationVARCHAR(30),

in_address1VARCHAR(30),

in_address2VARCHAR(30),

zipcodeVARCHAR(10),

OUTout_statusVARCHAR(30))

BEGIN

DECLARECONTINUEHANDLER

FOR1062

SETout_status='Duplicate Entry';

SETout_status='OK';

INSERTINTOlocations

(location,address1,address2,zipcode)

VALUES

(in_location,in_address1,in_address2,zipcode);

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代码  

CREATEPROCEDUREsp_not_found()

READS SQL DATA

BEGIN

DECLAREl_last_rowINTDEFAULT0;

DECLAREl_dept_idINT:

DECLAREc_deptCURSORFOR

SELECTdepartment_idFROMdepartments;

DECLARECONTINUEHANDLERFORNOTFOUNDSETl_last_row=1;

OPENc_dept;

dept_cursor: LOOP

FETCHc_deptINTOl_dept_id;

IF (l_last_row=1)THEN

LEAVE dept_cursor;

ENDIF;

ENDLOOP dept_cursor;

CLOSEc_dept;

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代码  

CREATEPROCEDUREsp_add_department

(p_department_nameVARCHAR(30),

p_manager_surnameVARCHAR(30),

p_manager_firstnameVARCHAR(30),

p_locationVARCHAR(30),

OUTp_sqlcodeINT,

OUTp_status_messageVARCHAR(100))

BEGIN

/* STARTDeclareConditions */

DECLAREduplicate_key CONDITIONFOR1062;

DECLAREforeign_key_violated CONDITIONFOR1216;

/*ENDDeclareCOnditions */

/* STARTDeclarevariablesandcursors */

DECLAREl_manager_idINT;

DECLAREcsr_mgr_idCURSORFOR

SELECTemployee_idFROMemployees

WHEREsurname=UPPER(p_manager_surname)

ANDfirstname=UPPER(p_manager_firstname);

/*ENDDeclarevariablesandcursors */

/* STARTDeclareException Handlers */

DECLARECONTINUEHANDLERFORduplicate_key

BEGIN

SETp_sqlcode=1052;

SETp_status_message='Duplicate key error';

END;

DECLARECONTINUEHANDLERFORforeign_key_violated

BEGIN

SETp_sqlcode=1216;

SETp_status_message='Foreign key violated';

END;

DECLARECONTINUEHANDLERFORNOTFOUND

BEGIN

SETp_sqlcode=1329;

SETp_status_message='No record found';

END;

/*ENDDeclareException Handlers */

/* START Execution */

SETp_sqlcode=0;

OPENcsr_mgr_id;

FETCHcsr_mgr_idINTOl_manager_id;

IF p_sqlcode<>0THEN/* Failedtoget manager id */

SETp_status_message=CONCAT(p_status_message,' when fetching manager id');

ELSE/* Got manager id, we can tryandinsert*/

INSERTINTOdepartments (department_name, manager_id, location)

VALUES(UPPER(p_department_name), l_manager_id,UPPER(p_location));

IF p_sqlcode<>0THEN/* Failedtoinsertnew department */

SETp_status_message=CONCAT(p_status_message,' when inserting new department');

ENDIF;

ENDIF;

CLOSEcsr_mgr_id;

/*ENDExecution */

END

mysql存储过程捕获错误处理_mysql存储过程之异常处理篇相关推荐

  1. 为什么mysql调用存储过程总是错误_使用存储过程时一个错误的解决方法_MySQL

    jackxm(原作) 这段时间用了一下C Builder ,在调用存储过程的时候遇到了一些问题,问了很多地方都没有找到答案,最后还是靠自己,现在拿出来和大家分享. 示例代码: StoredProc1- ...

  2. mysql中的存储过程是什么意思_mysql存储过程是什么

    mysql存储过程:首先操作数据库语言SQL语句在执行的时候需要要先编译:然后执行,而存储过程是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数来调用执 ...

  3. mysql 存过 if语句_mysql存储过程 if 语句

    MySql的存储过程 存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来执行已经定义好的SQL语句.存储过程和函数可以避免开发人员重复的编写相同的SQL语句.而且,存 ...

  4. mysql存储过程写法简书_Mysql存储过程

    存储过程简介 SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储 ...

  5. 简述mysql的存储的优点_MySQL 存储过程 优点和缺点有哪些?

    存储过程的优点主要包括以下几点: 第一点,性能提高.这是相对于不适用存储过程来说的,因为存储过程在创建的时候就编译好了,而后每次调用都不会再次编译,这相对于传统的SQL语句中每次调用都需要编译的情况来 ...

  6. mysql存储过程和自定义函数_MySQL存储过程/存储过程与自定义函数的区别

    语法: 创建存储过程: CREATE[definer = {user|current_user}] PROCEDURE sp_name ([ proc_parameter [,proc_paramet ...

  7. mysql存储过参数拼接_mysql 存储过程动态拼接sql并执行赋值

    CREATE DEFINER = CURRENT_USER PROCEDURE `NewProc`(in _xnb varchar(50)) BEGIN ## 定义变量 DECLARE _num FL ...

  8. mysql 存储过程声明式游标_Mysql 存储过程中使用游标循环读取临时表

    游标 游标(Cursor)是用于查看或者处理结果集中的数据的一种方法.游标提供了在结果集中一次一行或者多行前进或向后浏览数据的能力. 游标的使用方式 定义游标:Declare 游标名称 CURSOR ...

  9. mysql存储过程if多命令_MySQL存储过程if-存储过程中的if-db2存储过程if多条件

    存储过程的if,else怎幺写? Oracle 是下面这种写法: IF testvalue > 100 THEN dbms_output.put_line( '100+' ); ELSIF te ...

最新文章

  1. java字符串转json取集合_Java中Json字符串直接转换为对象的方法(包括多层List集合)...
  2. mac下natapp使用
  3. Node.js Web 开发框架大全《中间件篇》
  4. kafka控制台模拟消费_Kafka 详解
  5. 判断字符串是否构成回文_构成字符串回文的最小删除数
  6. 前端学习(2641):懂代码之header表头页之控制全屏显示
  7. JZOJ5918【NOIP2018模拟10.20】Car
  8. Oracle DBA课程系列笔记(5)
  9. javascript设计模式系列
  10. vb用数组方式快速导出MSFlexGrid表格数据到Excel表格中
  11. 移动端页面兼容性问题解决方案整理
  12. POJ - 3624 (01背包问题)(动态规划-滚动数组)
  13. 【CS224n】(lecture1)课程介绍和word2vec
  14. 墨画子卿第一章第4节:世界观的颠覆
  15. Setup Factory导入注册表时丢失部分语句
  16. chrome浏览器 快捷键设置
  17. 电子学会2023年3月青少年软件编程(图形化)等级考试试卷(三级)真题,含答案解析
  18. 元宇宙时代NFT的价值衡量
  19. Sublime Text3 安装简体中文
  20. python杂记-逆波兰表达式求解

热门文章

  1. 火山引擎进军云市场,计划未来三年服务十万客户
  2. 云+X案例展 | 民生类: “中企通信 × TutorABC”共创全球数字教育科技新里程
  3. 这项技术:华为、BAT要力捧!程序员:我彻底慌了... ​
  4. 分布式系统与消息投递
  5. IDC敲黑板啦:未来企业IT以混合云为主
  6. Java语言用于定义接口的关键字是_定义类的保留字是(__)定义接口的保留字是(__);...
  7. github private链接访问_如何将Jenkins链接到私有Github存储库?
  8. mysql 聚簇索引和非聚簇索引_MySQL 聚簇索引 二级索引 辅助索引(上两期中奖名单)...
  9. Filezilla 服务器发回了不可路由的地址。使用服务器地址代替
  10. VS Code 常用快捷键