在MySQL中,特定异常需要特定处理。这些异常可以联系到错误,以及子程序中的一般流程控制。定义异常是事先定义程序执行过程中遇到的问题,异常处理定义了在遇到问题时对应当采取的处理方式,并且保证存储过程或者函数在遇到错误时或者警告时能够继续执行。

1 异常定义

1.1 语法

DECLARE condition_name CONDITION FOR [condition_type];

1.2 说明

condition_name参数表示异常的名称;

condition_type参数表示条件的类型,condition_type由SQLSTATE [VALUE] sqlstate_value|mysql_error_code组成:

sqlstate_value和mysql_error_code都可以表示MySQL的错误;sqlstate_value为长度为5的字符串类型的错误代码;mysql_error_code为数值类型错误代码;

1.3 示例

定义“ERROR 1148(42000)”错误,名称为command_not_allowed。可以有以下两种方法:

//方法一:使用sqlstate_value

DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000';

//方法二:使用mysql_error_code

DECLARE command_not_allowed CONDITION FOR 1148;

2 自定义异常处理

2.1 异常处理语法

DECLARE handler_type HANDLER FOR condition_value [,...] sp_statement

2.2 参数说明

handler_type: CONTINUE|EXIT|UNDO

handler_type为错误处理方式,参数为3个值之一;CONTINUE表示遇到错误不处理,继续执行;EXIT表示遇到错误时马上退出;UNDO表示遇到错误后撤回之前的操作,MySQL暂不支持回滚操作;

condition_value: SQLSTATE [VALUE] sqlstate_value| condition_name|SQLWARNING|NOT FOUND|SQLEXCEPTION|mysql_error_code

condition_value表示错误类型;SQLSTATE [VALUE] sqlstate_value为包含5个字符的字符串错误值;

condition_name表示DECLARE CONDITION定义的错误条件名称;SQLWARNING匹配所有以01开头的SQLSTATE错误代码;NOT FOUND匹配所有以02开头的SQLSTATE错误代码;SQLEXCEPTION匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;mysql_error_code匹配数值类型错误代码;

2.3 异常捕获方法

//方法一:捕获sqlstate_value异常

//这种方法是捕获sqlstate_value值。如果遇到sqlstate_value值为"42S02",执行CONTINUE操作,并输出"NO_SUCH_TABLE"信息

DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET

@info='NO_SUCH_TABLE';

//方法二:捕获mysql_error_code异常

//这种方法是捕获mysql_error_code值。如果遇到mysql_error_code值为1146,执行CONTINUE操作,并输出"NO_SUCH_TABLE"信息;

DECLARE CONTINUE HANDLER FOR 1146 SET

@info='NO_SUCH_TABLE';

//方法三:先定义条件,然后捕获异常

DECLARE no_such_table CONDITION FOR 1146;

DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET

@info='NO_SUCH_TABLE';

//方法四:使用SQLWARNING捕获异常

DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR';

//方法五:使用NOT FOUND捕获异常

DECLARE EXIT HANDLER FOR NOT FOUND SET @info='NO_SUCH_TABLE';

//方法六:使用SQLEXCEPTION捕获异常

DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';

3 综合示例

创建一个表,设置该表的主键,在不定义异常处理和定义异常处理情况下看执行到哪一步。

1

2

3

4

5

6

7

show

databases;

use wms;

create table location

(

location_id

int primary key,

location_name

varchar(50)

);

示例1:不定义异常情况下

1

2

3

4

5

6

7

8

9

10

11

12

DELIMITER

//

CREATE PROCEDURE handlerInsertNoException()

BEGIN

/*DECLARE

CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2=1;*/

SET @x=1;

INSERT INTO location

VALUES (1,'Beijing');

SET @x=2;

INSERT INTO location

VALUES (1,'Wuxi');

SET @x=3;

END;

//

DELIMITER

;

调用存储过程与结果:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

mysql>

call handlerInsertNoException();

ERROR 1062

(23000): Duplicate entry '1' for key 'PRIMARY'

mysql>

select @x;

+------+

|

@x   |

+------+

|

2 |

+------+

1 row in set (0.00 sec)

mysql>

select * from location;

+-------------+---------------+

|

location_id | location_name |

+-------------+---------------+

|

1 | Beijing       |

+-------------+---------------+

1 row in set (0.00 sec)

注意:操作示例2前要清空表中数据,并退出重新登录,以免客户端变量@x影响,详细说明参见结论中的第一点。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

mysql>

truncate table location;

Query OK,

0 rows affected (0.04 sec)

mysql>

select * from location;

Empty set (0.00 sec)

mysql>

exit;

Bye

david@Louis:~$

mysql -u root -p

Enter

password:

Welcome to the MySQL

monitor.  Commands end with ; or \g.

Your MySQL

connection id is 53

Server

version: 5.5.38-0ubuntu0.14.04.1 (Ubuntu)

mysql>

use wms;

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>

select * from location;

Empty set (0.00 sec)

mysql>

select @x;

+------+

|

@x   |

+------+

| NULL |

+------+

1 row in set (0.00 sec)

示例2:定义异常处理情况下:

1

2

3

4

5

6

7

8

9

10

11

12

DELIMITER

//

CREATE PROCEDURE handlerInsertWithException()

BEGIN

DECLARE CONTINUE HANDLER

FOR SQLSTATE '23000' SET @x2=1;

SET @x=1;

INSERT INTO location

VALUES (1,'Beijing');

SET @x=2;

INSERT INTO location

VALUES (1,'Wuxi');

SET @x=3;

END;

//

DELIMITER

;

调用存储过程与结果:

1

2

3

4

5

6

7

8

9

10

mysql>

CALL handlerInsertWithException();

Query OK,

0 rows affected (0.09 sec)

mysql> select @x;

+------+

|

@x   |

+------+

|

3 |

+------+

1 row in set (0.00 sec)

mysql> select @x,@x2//

+——+——+

| @x   | @x2  |

+——+——+

| 3    | 1    |

+——+——+

1 row in set (0.00 sec)

以上显示结果是@x=3,@x2=1,和上面分析的情况相同,说明程序运行无误。

说明与结论:

一、MySQL中,@var_name表示用户变量,使用SET语句为其赋值,用户变量与连接有关,一个客户端定义的变量不能被其他客户端看到或者使用。当客户端退出时,该客户端连接的所有变量将自动释放。

二、在示例1中,由于注释了异常的声明"",此时向表中插入相同主键,就会触发异常,并且采取默认(EXIT)路径;且查看此时的@x返回2,表示下面的INSERT语句并没有执行就退出了.

三、定义了异常处理,此时遇到错误也会按照异常定义那样继续执行;但只有第一条数据被插入到表中,此时用户变量@x=3说明已经执行到了结尾;

DECLARE CONDITION环境声明    在进行错误处理的时候,可以使用SQLSTATE或指定一个错误代码,实际上,也可以给他们定义一个名字,然后在进行处理的时候使用定义的名字。比如看下面这个例子:

mysql> create procedure pro18()

-> begin

-> declare`constraint violation` condition for sqlstate

’23000′;#注意constraint violation两侧的是“`”,即Tab键上边,1键左边的按键,不是单引号,写成单引号会报错

-> declare exit handler for `constraint violation`

rollback;#注意constraint violation两侧的是“`”

-> start transaction;

-> insert into t2(s1) values(1);

-> insert into t2(s1) values(1);

-> commit;

-> end;//

Query OK, 0 rows affected (0.00 sec)

首先给sqlstate ’23000′定义了一个名字`constraint

violation`,在进行操作的时候,就直接可以用这个名字了。t2表是一个innodb表,所以对这个表的插入操作都会ROLLBACK回滚,在这 里例子中,由于主键插入两个同样的值导致sqlstate 23000错误发生,导致回滚事件发生。sqlstate 23000是约束错误。

下面调用这个存储过程并查看运行结果:

mysql> call pro18()//

Query OK, 0 rows affected (0.04 sec)

mysql> select * from t2//

Empty set (0.01 sec)

可以看到t2中没有插入任何记录,全部事务都回滚了。

下面再来介绍几个声明条件,首先看例子:

mysql> create procedure pro19()

-> begin

-> declare exit handler for not found begin end;

-> declare exit handler for sqlexception begin end;

-> declare exit handler for sqlwarning begin end;

-> end;//

Query OK, 0 rows affected (0.00 sec)

这个例子展示了三个预条件声明:NOT FOUNT是找不到行,SQLEXCEPTION是错误,SQLWARNING是警告或注释;这三个条件声明是预声明,所以不需要声明条件就可以使用。但 是如果使用:declare sqlexception condition….这种格式的话,就会报错。

错误代码

1011 HY000 Error on delete of ''%s'' (errn %d)

1021 HY000 Disk full (%s); waiting for someone to free some space . . .

1022 23000 Can''t write; duplicate key in table ''%s''

1027 HY000 ''%s'' is locked against change

1036 HY000 Table ''%s'' is read only

1048 23000 Column ''%s'' cannot be null

1062 23000 Duplicate entry ''%s'' for key %d

1099 HY000 Table ''%s'' was locked with a READ lock and can''t be updated

1100 HY000 Table ''%s'' was not locked with LOCK TABLES

1104 42000 The SELECT would examine more than MAX_JOIN_SIZE rows; check your

WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is

okay

1106 42000 Incorrect parameters to procedure ''%s''

1114 HY000 The table ''%s'' is full

1150 HY000 Delayed insert thread couldn''t get requested lock for table %s

1165 HY000 INSERT DELAYED can''t be used with table ''%s'' because it is locked

with LOCK TABLES

1242 21000 Subquery returns more than 1 row

1263 22004 Column set to default value; NULL supplied to NOT NULL column ''%s''

at row %ld

1264 22003 Out of range value adjusted for column ''%s'' at row %ld

1265 1000 Data truncated for column ''%s'' at row %ld

1312 0A000 SELECT in a stored program must have INTO

1317 70100 Query execution was interrupted

1319 42000 Undefined CONDITION: %s

1325 24000 Cursor is already open

1326 24000 Cursor is not open

1328 HY000 Incorrect number of FETCH variables

1329 2000 No data to FETCH

1336 42000 USE is not allowed in a stored program

1337 42000 Variable or condition declaration after cursor or handler

declaration

1338 42000 Cursor declaration after handler declaration

1339 20000 Case not found for CASE statement

1348 HY000 Column ''%s'' is not updatable

1357 HY000 Can''t drop a %s from within another stored routine

1358 HY000 GOTO is not allowed in a stored program handler

1362 HY000 Updating of %s row is not allowed in %s trigger

1363 HY000 There is no %s row in %s trigger

存储过程是mysql高级编程的一大特色,当然存储过程包括了很多的知识,包括错误处理,预定义等,下面让我们首先看一下错误处理的部分。

定义错误:

为错误定义一个名称,语法为:

DECLARE error_name CONDITION FOR condition_value;

declare 定义一个变量

error_name:自定义的错误的名字

condition_value可以是两种情况:

第一:直接写错误号,如 1305;

第二:写sqlstate错误号: 如

SQLSTATE '42000';

错误处理

语法为:

DECLARE handler_type HANDLER FOR condition_value

begin

...

end;

handler_type: 处理的过程。

CONTINUE 继续执行未完成的存储过程,直至结束。(常用,默认)

| EXIT 出现错误即自动跳出所在的begin不再执行后面的语句。

condition_value: 处理的触发条件

SQLSTATE [VALUE] sqlstate_value 不用说了,就是上面提到的第二中方法,也是最常用的错误定义,自己去查错误列表吧。

| condition_name 我们刚刚定义的那个名字errorname就是用在这里的。

| SQLWARNING 代表所有以01开头的错误代码

| NOT FOUND 表所有以02开头的错误代码,当然也可以代表一个游标到达数据集的末尾。

| SQLEXCEPTION 代表除了SQLWARNING和NOT FOUND 的所有错误代码。

| mysql_error_code 错误编号,上面的第一种方法,不过同样可以在错误列表从中查到,是我比较常用的。

例子:

create procedure error_test()

begin

#定义错误,1305是调用了错误的存储过程

declare errname condition for 1305;

declare continue handler for errname

begin

select 'no that procedure' as error;

end;

call aaa();end;

备注:

如果需要查看更多的错误列表可以直接到MySQL安装路径下。

比如我的/usr/local/mysql/share/mysql/errmsg.txt

说明:SQLSTATE [VALUE] sqlstate_value这种格式是专门为ANSI SQL 和 ODBC以及其他的标准.

并不是所有的MySQL ERROR CODE 都映射到SQLSTATE。

mysql异常处理_MySQL定义异常和异常处理方法相关推荐

  1. MySQL定义异常和异常处理方法

    MySQL定义异常和异常处理方法 参考文章: (1)MySQL定义异常和异常处理方法 (2)https://www.cnblogs.com/yizitrd/p/5445071.html 备忘一下.

  2. mysql定义外键_MySQL定义外键的方法

    MySQL定义外键的方法是每个学习MySQL的人都需要掌握的知识,下文就对MySQL定义外键的语句写法进行了详细的阐述,供您参考. 外键为MySQL带来了诸多的好处,下面就为您介绍MySQL定义外键的 ...

  3. 空间mysql升级_MySQL升级的3种方法

    MySQL数据库的版本更新很快,新的特性也随之不断的更新,更主要的是解决了很多影响我们应用的BUG,为了让我们的MySQL变得更美好,我们有必要去给它升级,尽管你会说它现在已经跑得很好很稳定完全够用了 ...

  4. c远程连接mysql数据库_MySQL数据库远程连接开启方法

    第一中方法:比较详细 以下的 文章 主要介绍的是 MySQL 数据库 开启远程连接的时机操作流程,其实开启MySQL 数据库远程连接的实际操作步骤并不难,知识方法对错而已,今天我们要向大家描述的是My ...

  5. php mysql 去重_mysql去重的两种方法实例详解

    这篇文章主要介绍了mysql去重的两种方法详解及实例代码的相关资料,这里对去重的两种方法进行了一一实例详解,需要的朋友可以参考下 mysql去重 方法一: 在使用MySQL时,有时需要查询出某个字段不 ...

  6. mysql 远程_MYSQL开启远程访问权限的方法

    1.登陆mysql数据库 mysql -u root -p 查看user表 mysql> use mysql; Database changed mysql> select host,us ...

  7. mycat连接mysql时间_mysql连接异常及mycat报sql timeout问题

    1.mysql部署为一主两从,单库最大连接数为10000:版本为5.7 2.mycat采用分表,有5到6个表采用分表模式:最大一张表,分了256张表,其次分了64,其他的大概是10张左右:版本为1.6 ...

  8. java 异常继承体系_1、异常概述和继承体系 2、原因及处理方式 3、运行时异常 4、重写异常处理 5、Throwable类常见方法 6、自定义异常...

    01异常的概述 * A: 异常的概述 * a:什么是异常 * Java代码在运行时期发生的问题就是异常. * b:异常类 * 在Java中,把异常信息封装成了一个类. * 当出现了问题时,就会创建异常 ...

  9. python中语法错误-Python语法错误与异常及异常处理方法

    回顾 在Python进阶记录之基础篇(二十)中,我们介绍了Python面向对象中的类方法和静态方法,以及类中拥有特殊功能的魔法函数.需要重点掌握类方法和静态方法的概念和基本用法,理解魔法函数的作用冰女 ...

最新文章

  1. SpringCloud Alibaba微服务实战(六) - 路由网关(Gateway)
  2. .f90文件批量转为dll文件_办公必备神器DropIt V8.5.1Portable文件整理分类工具
  3. java wmi_WMI依赖服务使用WMI查询
  4. [原创]FineUI秘密花园(二十一) — 表格之动态创建列
  5. python设计编程体验中心_试学了风变编程的Python小课体验课,觉得课程模式很有趣,报名正式课程应该注意什么?...
  6. 大熊猫学生网页设计模板 静态HTML动物保护学生网页作业成品 DIV CSS大熊猫野生动物主题静态网页
  7. jstl core and jstl fn
  8. 为什么至今为止有些人的电脑系统还在使用XP?
  9. mysql数据库文件怎么用_mysql数据库文件怎么用
  10. 及时复盘的好处_及时复盘,促进成长
  11. MyBatis中mapper.xml其属性resultSets的作用及研究
  12. 153870-20-3,S-acetyl-PEG3-alcohol羟基可以反应进一步衍生化合物
  13. 电话机漏电流大引起电话交换机振铃
  14. Win10系统无法启动的最终解决方案
  15. freeswitch呼入落地测试信息
  16. 外呼系统与网络电话有什么差别?应该怎么选?
  17. 促销活动表结果的学习探讨
  18. 2019_GDUT_新生专题V算法优化 B. A Simple Problem with Integers POJ 3468
  19. 记载几个ubuntu的源(heanet,163,eud类的)___不仅仅是ubuntu source
  20. wine安装RTX、QQ、飞信

热门文章

  1. 图片文字转word文档的巧妙方法
  2. java面试问题总结
  3. 如何Keil官网下载器件支持包Software Packs
  4. IOS 常用开源框架
  5. 看过的最好的护肤心得
  6. 便携式户外电源芯片CS32F031C8T6
  7. 同态加密库Seal库的安装(win11+VS2022)
  8. Qt 对 wav 音频文件进行剪切
  9. 基于单片机的A/D数字电压表设计(电路+程序)
  10. 无线网卡怎么样?无线网卡怎么安装?