声明异常处理的语法

DECLARE
{EXIT | CONTINUE}
HANDLER FOR
{error-number | SQLSTATE error-string | condition}
SQL statement

上述定义包括:

Handler Type (CONTINUE,EXIT)//处理类型 继续或退出

Handler condition (SQLSTATE,MYSQL ERROR,CONDITION)//触发条件

Handler actions(错误触发的操作)

注意:

1、exit只退出当前的block。exit 意思是当动作成功提交后,退出所在的复合语句。即declare exit handler for... 所在的复合语句。

2、如果定义了handler action,会在continue或exit之前执行

发生错误的条件有:

1、MYSQL错误代码

2、ANSI-standard SQLSTATE code

3、命名条件。可使用系统内置的SQLEXCEPTION,SQLWARNING和NOT FOUND

例1:

当错误代码为1062时将duplicate_key的值设为1,并继续执行当前任务

declare continue handler for 1062 set duplicate_key=1;

下面的跟上面一样,只是使用的条件为ANSI标准错误代码

declare continue handler for sqlstate '23000' set duplicate_key=1;

当发生SQLEXCEPTION时,将L_error设为1,并继续

declare continue handler for SQLEXCEPTION set L_error=1;

小提示:

当你在MYSQL客户端执行命令并产生错误时,会得到MYSQL和ANSI的SQLSTATE code,如:

附常见错误号对照表

MySQL error code SQLSTATE code Error message

1011 HY000 Error on delete of '%s' (errno: %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

命名条件:

declare conditon_name condition for {SQLSTATE sqlstate_code | MYSQL_ERROR_CODE};

例如:

declare foreign_key_error condition for 1216;

declare continue handler for foreign_key_error mysql_statements;

优先级:当同时使用MYSQL错误码,标准SQLSTATE错误码,命名条件(SQLEXCEPTION)来定义错误处理时,其捕获顺序是(只捕获一条错误):MYSQL码->SQLSTATE->命名条件

作用域:

1、包括begin...end内的语句

declare continue handler for 1048 select 'attempt to insert a null value';
begin
insert into a values(6,null);
end;

若a表第二字段定义为非空,则会触发1048错误

2、若错误处理在begin...end内定义,则在之外的语句不会触发错误发生

BEGIN
BEGIN
DECLARE CONTINUE HANDLER FOR 1216 select 'Foreign key constraint violated';
END;
INSERT INTO departments (department_name,manager_id,location) VALUES ('Elbonian HR','Catbert','Catbertia');
END;

3、能够捕获其它存储过程抛出的错误

下面再通过几个例子来掌握MySQL存储过程中异常处理的使用。

例一:error-number

准备工作

CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
CREATE TABLE `t2` (
`cid` INT(10) UNSIGNED NULL DEFAULT NULL,
INDEX `FK__t1` (`cid`),
CONSTRAINT `FK__t1` FOREIGN KEY (`cid`) REFERENCES `t1` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

创建存储过程

delimiter //
create procedure a(var1 int)
begin
declare exit handler for 1452 insert into error_log values(
concat('time:',current_date,'.Foreign Key Reference Failure For Value=',var1)
);
insert into t2 values(var1);
end;//

如果有1452错误,则当插入到表error_log这个语句完成后,退出(exit),这里申明异常处理的语句在上面begin...end的复合语句中,所以这里退出,其实就表示退出了该存储过程。

例二:sqlstate error-string

准备工作

CREATE TABLE `t4` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
create procedure p23()
begin
begin
declare exit handler for sqlstate '23000' set @x2=1;
set @x=1;
insert into t4 values(1);
set @x=2;
end;
begin
declare exit handler for sqlstate '23000' set @x2=9;
insert into t4 values(1);
end;
set @x=3;
end

结果:

例三:

begin
declare exit handler for sqlstate '23000' set @x2=1;
set @x=1;
insert into t4 values(1);
set @x=2;
begin
declare exit handler for sqlstate '23000' set @x2=9;
insert into t4 values(1);
end;
set @x=3;
end

结果:

在执行一次该存储过程,得到结果如下:

error-number的例子

create procedure p22(var1 int)
begin
declare exit handler for 1216 insert into error_log values(
concat('time:' , current_date , '.Foreign Key Reference Failure For Value='
,var1)
);
insert into t3 values(var1);
end;//

sqlstate error-string的例子

create procedure p23()
begin
declare continue handler for sqlstate '23000' set @x2=1;
set @x=1;
insert into t4 values(1);
set @x=2;
insert into t4 values(1);
set @x=3;
end;//

执行结果:

condition的例子

declare 'name' condition for sqlstate '23000';
declare exit handler for 'name' rollback;

declare handler 声明异常处理的语法的更多相关文章

  1. 翻译:DECLARE HANDLER语句(已提交到MariaDB官方手册)

    本文为mariadb官方手册:DECLARE HANDLER的译文. 原文:https://mariadb.com/kb/en/library/declare-handler/我提交到MariaDB官 ...

  2. 『忘了再学』Shell基础 — 19、使用declare命令声明变量类型

    目录 1.declare命令介绍 2.声明数组变量类型 3.声明变量为环境变量 4.声明只读属性 5.补充: 1.declare命令介绍 Shell中所有变量的默认类型是字符串类型,如果你需要进行特殊 ...

  3. Berry 异常处理 1: 语法和字节码设计

    语法 最近在实现 Berry 的异常处理特性,进过初步的调查后决定使用类似 Python 的 try-except 异常处理模式,为此要引入三个新的关键字: try:表示异常捕获块的开始,位于异常捕获 ...

  4. Block的声明与定义语法

    Block的声明 Block的声明与函数指针的声明类似 返回值类型(^变量名)(参数列表) Block的定义 ^返回值类型(参数列表) { 表达式 } 其中: 1 如果返回值类型是void,可以省略 ...

  5. 存储过程/游标/mysql 函数

    存储过程和函数(存储在 mysql数据库中的 proc表,所以检查有没有这个表)存储过程是一种存储程序(如正规语言里的子程序一样),mysql支持有两种:存储过程,在其他SQL语句中可以返回值的函数( ...

  6. MYSQL异常和错误机制

    BEGIN ; ; ; START TRANSACTION; call put_playerbehavior(i_playerid,i_gameid,i_channelid,i_acttime,@a) ...

  7. ORACLE中声明变量:define variable declare

    在sqlplus 环境中,声明变量的关键字:define variable declare 一.define关键字(host变量) host变量的作用是一个替换作用,是主机环境与oracle进行交互的 ...

  8. C语言复杂声明-void (*signal(int sig, void (*handler)(int)))(int);

    问题提出 请分析此声明:void (*signal(int sig, void (*handler)(int)))(int); 求解过程 在对上面的例子作分析之前,我们需要了解C语言的声明优先级,&l ...

  9. Mysql Condition /Handler(异常处理)

    关于介绍,可参见:http://www.cnblogs.com/end/archive/2011/04/01/2001946.html. http://blog.csdn.net/rdarda/art ...

随机推荐

  1. MyBatis联合查询association使用

    1.需求 两张表 channels(频道表)  member(会员表) 频道表里面有会员id,查询频道列表的时候需要关联查询出会员的名称,头像等信息 . 2.channels.xml定义,配置主要在这 ...

  2. 安装mysql5.7后无法启动,/var/run/mysqld 目录每次重启后都需要手动去创建--终极解决方案

    鉴于很多童鞋反应,mysql5.7安装后出现无法启动,建立/var/run/mysqld 并赋权mysql用户解决了启动的问题,但是重启系统后又出现无法启动的问题,导致/var/run/mysqld ...

  3. 【P2774】方格取数问题(贪心+最大流,洛谷)

    首先,我们要读懂这道题,否则你会和我一开始产生一样的疑问,把所有的数都取走剩下一个最小的不就可以了么???然后我们发现样例完全不是这么回事.题目中所说的使相邻的两个数没有公共边,是指你去走的数,也就是 ...

  4. c#.NET中日志信息写入Windows日志中解决方案

    1. 目的应用系统的开发和维护离不开日志系统,选择一个功能强大的日志系统解决方案是应用系统开发过程中很重要的一部分.在.net环境下的日志系统解决方案有许多种,log4net是其中的佼佼者.在Wind ...

  5. jquery01-简介+语法+选择器+事件

    jQuery是一个JavaScript函数库,是一个轻量级的"写的少,做的多"的JavaScript库,包含以下功能: HTML 元素选取 HTML 元素操作 CSS 操作 HTM ...

  6. Linux嵌入式 -- 内核 - 内核链表

    1. linux内核链表 链表数据结构的定义: struct list_head  {  struct list_head *next, *prev;  };  list_head结构包含两个指向li ...

  7. RGB(16进制)_转_TColor

    ZC:内存中 COLORREF就是一个DWORD(从定义"COLORREF = DWORD;"就可以看出来),但是 具体的byte R/G/B 的位置是怎么方式的? ZC:Wind ...

  8. 返回结果的HTTP状态码

    HTTP状态码的职责是当客户端向服务器发送请求时,描述返回的请求结果. 2xx成功 2xx的响应结果表明请求被正常处理. 200 OK 请求已正常处理 204 No Content 请求处理成功,但是 ...

  9. Git学习--版本回退

    现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下: Git is a distributed version control system. ...

  10. VueJs路由跳转——vue-router的使用

    对于单页应用,官方提供了vue-router进行路由跳转的处理,本篇主要也是基于其官方文档写作而成. 安装 基于传统,我更喜欢采用npm包的形式进行安装. npm install vue-router ...