赞
踩
什么是异常
所写的程序在执行过程中可能会出错,运行时的错误就是异常。
在MySQL中,当存储过程运行出错时,存储过程终止执行并抛出错误信息。
什么情况下需要异常处理插入数据违反唯一约束;
插入或更新的数据超过字段最大长度;
更新数据与期望的结果不一致。如更新1条数据,却显示更新了5条。
定义异常处理条件
定义异常条件语法DECLARE 条件名称 CONDITION FOR [条件类型]
条件名称:自定义的名称,建议见名知意
条件类型:mysql_error_code | SQLSTATE sqlstate_value
mysql_error_code和sqlstate_value,sqlstate_value是长度为5的字符串类型错误代码,mysql_error_code为数值类型错误代码。如ERROR 1142(42000)中,sqlstate_value的值是42000,mysql_error_code的值是1142。
定义异常条件简单案例# 方式一
DECLATE notAllowed CONDITION FOR SQLSTATE '42000';
# 方式二
DECLARE notAllowed CONDITION FOR 1142;
定义条件处理程序语法DECLARE 处理类型 HANDLER FOR 条件类型
处理类型:CONTINUE、EXIT
CONTINUE:表示遇到错误不处理,继续执行;
EXIT:表示遇到错误立即退出;
条件类型:其取值为SQLSTATE [VALUE] sqlstate_value、condition_name、SQLWARNING、NOT FOUND、SQLEXCEPTION、mysql_error_codeSQLSTATE[VALUE] sqlstate_value 包含5个字符串的字符串错误值;
condition_name表示DECLARE CONDITION定义的错误条件名称;
SQLWARNING匹配所有以01开头的SQLSTATE错误代码;
NOT FOUND 匹配所有以02开头的SQLSTATE错误代码。主要用于游标或select into 变量名;
SQLEXCEPTION匹配所有没有被SQLWARNING捕获的SQLSTAT错误代码;
mysql_error_code匹配数值类型错误代码
定义异常处理程序案例方式# 方式一 捕获sqlstate_value
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info='noSuchTable';
# 方式二 捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'noSuchTable';
# 方式三 先定义条件
DECLARE noSuchTable CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR noSuchTable SET @info='noSuchTable';
# 方式四 SQLWARNING
DECLARE EXIT HANDLER FOR SQLWARNING SET @info='error';
# 方式五 NOT FOUND
DECLARE EXIT HANDLER FOR NOT FOUND SET @info='not found';
# 方式六 SQLEXCEPTION
DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='sqlexception';
异常处理案例
创建表CREATE TABLE `user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(60) COLLATE utf8_unicode_ci,
`email` varchar(40) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name_and_email` (`name`(20),`email`(20))
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
案例一、使用存储过程创建2张相同的表
错误案例DROP PROCEDURE IF EXISTS demo03//
create procedure demo03()
begin
create table t1(id int);
create table t1(id int);
select 'ziruchu';
end//
mysql> call demo03()//
ERROR 1050 (42S01): Table 't1' already exists调用存储过程,由于报错导致 t1表后面的select语句没有执行,若要后面的select语句执行,就需需要忽略报错的地方,然后顺利执行select语句,这就使用到了mysql异常处理。
正确案例# 方式一、定义条件结合条件异常处理
delimiter //
DROP PROCEDURE IF EXISTS demo03//
create procedure demo03()
begin
# 定义条件
declare existed condition for 1050;
# 条件异常处理,并定义一个变量
declare continue handler for existed set @fail = 1;
create table t1(id int);
create table t1(id int);
select 'ziruchu';
end//
# 调用存储过程
# 可以看到,错误被忽略,ziruchu被输出
call demo03()//
# 方式二、直接使用条件处理程序
DROP PROCEDURE IF EXISTS demo03//
create procedure demo03()
begin
declare exit handler for sqlstate '42S01' select '42S01异常';
create table t1(id int);
create table t1(id int);
select 'ziruchu';
end//
call demo03()//方式一:使用continue关键字,即遇到错误并跳过它,执行后面的程序,因此就可以看到 ziruchu 被输出了。
方式二:使用exit关键字,即遇到错误立即停止后面的程序执行,且遇到错误后执行条件异常处理程序后的一个语句,并终止后面的程序执行,因此方式二输出了 '42S01异常'
测试mysql> call demo0()//
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
delimiter //
DROP PROCEDURE IF EXISTS demo04//
create procedure demo04()
begin
declare continue handler for SQLSTATE '23000' set @a=1;
insert into t1 values (1);
insert into t1 values (1);
end//
delimiter //
DROP PROCEDURE IF EXISTS demo04//
create procedure demo04()
begin
declare continue handler for 1062 set @a=1;
insert into t1 values (1);
insert into t1 values (1);
select 'ziruchu';
end//注意:SQLSTATE后的错误码必须是字符串,因此必须加引号;for后直接跟mysql_error_code,错误码必须是数值。
我是小白,期待和优秀的你一起同行!
小白
2020年11月19日
转载:感谢您对自如初博客网站的认可,所有文章均属原创文章,技术类文章转载请注明出处,“自如初博客”;文学类文章请带文本链接地址,否则视为侵权!
很赞哦!(4)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。