声明异常处理的语法

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. spring security在spring mvc的action中获取登录人信息

    @RequestMapping("/index") public ModelAndView login( @RequestParam(value = "error&quo ...

  2. 51nod 1289 大鱼吃小鱼 栈

    1289 大鱼吃小鱼 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条 ...

  3. 爬虫之MongoDB

    一.简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库 1.易用性 MongoDB是一个面向文档(document-oriented)的数据库,而不是关系型数据库. 不采用关系型主要是为了 ...

  4. SqlCacheDependency:asp.net SQL缓存依赖

    先看下MSDN对此类的介绍: 在以下两者之间建立关系:一是在 ASP.NET 应用程序的 Cache 对象中存储的项:二是特定 SQL Server 数据库表或  SQL Server 2005 查询 ...

  5. Sharded数据分片定位数据

    [http://www.tuicool.com/articles/UNnqUnU] Jedis分片 动机 在普通的Redis主/从方式,通常有一个主服务器负责"write"请求,多 ...

  6. 关于WM8741对于32位音频的支持

    WM8741据说是支持到32位192K,但实际上,对于32位,它只是支持I2S总线上32位数据输入,内部还是转换成24位来做滤波处理的,DA转换的精度是达不到32位的.不过它在转换到24位的时候有一个 ...

  7. iOS-文本转语音

    - 文本转语音 iOS提供了一个类AVSpeechSynthesizer来实现文本到语音的功能, 即读出文字 直接上代码: AVSpeechSynthesizer *synthesizer = [[A ...

  8. Idea_学习_09_Idea 方法自动生成参数默认名

    一.方法 1.快捷键 生成方法后,还空着参数,可以使用 ctrl + alt + 空格 ,列出参数,然后选择参数即可. 2.使用插件 二.参考资料 1.Intellij Idea 方法自动生成参数默认 ...

  9. sass入门篇

    CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作. 通俗的说,“CSS ...

  10. FMDB的操作(转),这篇比我写的好

    直接看吧 http://blog.devtang.com/blog/2012/04/22/use-fmdb/