一、异常处理的理解

ERROR 1062 (23000): Duplicate entry ‘2’ for key ‘PRIMARY’

错误 4位error code(5位sql statis):错误内容

二、异常处理的重要性

没有异常处理的存储过程,执行过程中非常难以预测执行结果。

建议:存储过程中加上异常处理部分。

三、异常处理的实现

异常处理的格式:

DECLARECONTINUE/EXITHANDLER FORSQLSTATE ‘23000’ (错误代码)

1.错误是什么?

eg:1062(23000)

2.怎么处理错误?

先执行SQL,再执行EXIT/CONTINUE

小结:

针对什么错误,首先执行SQL语句,可以是一个begin..end;语句块;

根据是continue还是exit,确定是接着执行还是退出begin..end;

接着执行的话,就是接着执行出错的SQL的下一条语句;

如果是退出,就退出这个declare所在的begin…end。

例子1:

DELIMITER $$

CREATE PROCEDURE small_mistake1(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' --》这是个异常

SET error = '23000'; //用来记录错误发生时的一些信息,异常捕获、处理

select error;

SET error = '00000';

select error;

INSERT INTO TEAMS VALUES(2,27,'third');

SET error = '23001';

END$$

DELIMITER ;

执行结果:

mysql> call small_mistake1(@a); --》上来直接就是select error,因为先执行sql

+-------+

| error |

+-------+

| NULL |

+-------+

1 row in set (0.00 sec)

+-------+

| error |

+-------+

| 00000 |

+-------+

1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> select @a; --》

+-------+

| @a |

+-------+

| 23001 |

+-------+

1 row in set (0.00 sec)

===例子2:

CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));

delimiter $$

CREATE PROCEDURE handlerdemo ()

BEGIN

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

SET @x = 1;

INSERT INTO test.t VALUES (1); ---》能执行

SET @x = 2; --》报错,因为@x==1

INSERT INTO test.t VALUES (1);

SET @x = 3;

END$$

delimiter ;

CALL handlerdemo()

执行结果:

mysql> select @x2; --》捕获到异常,就令x2=1

+------+

| @x2 |

+------+

| 1 |

+------+

1 row in set (0.00 sec)

mysql> select @x; --》set @x=3

+------+

| @x |

+------+

| 3 |

+------+

1 row in set (0.00 sec)

===例子3:

DELIMITER $$

CREATE PROCEDURE small_mistake2(

OUT error VARCHAR(5))

BEGIN

DECLARE EXIT HANDLER FOR SQLSTATE '23000' --》EXIT直接退出begin..end

SET error = '23000';

select error;

SET error = '00000';

select error;

INSERT INTO TEAMS VALUES(2,27,'third');

--》此语句出错,捕获到异常后,因为是exit,所以不会再执行下面的set error='23001'语句

SET error = '23001';

END$$

DELIMITER ;

mysql> call small_mistake2(@a); --》先执行sql

+-------+

| error |

+-------+

| NULL |

+-------+

1 row in set (0.00 sec) --》捕获到异常

+-------+

| error |

+-------+

| 00000 |

+-------+

1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> select @a; ---》证明没有执行set error='23001'

+-------+

| @a |

+-------+

| 23000 |

+-------+

1 row in set (0.00 sec)

===例子4:一个begin后面可以接多个DECLARE

DELIMITER $$

CREATE PROCEDURE small_mistake3(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000'

SET error = '23000';

DECLARE CONTINUE HANDLER FOR SQLSTATE '21S01'

SET error = '21S01';

INSERT INTO TEAMS VALUES(2,27,'third',5);

END$$

DELIMITER ;

mysql> call small_mistake3(@error);

Query OK, 0 rows affected (0.00 sec)

mysql> select @error;

+--------+

| @error |

+--------+

| 21S01 |

+--------+

1 row in set (0.00 sec)

四、错误捕获快捷方式

异常处理的好处:

①出错不报错

②出错可以进行处理;记录出错时的一些信息

③处理所有的错误:

===例子1:

DELIMITER $$

CREATE PROCEDURE small_mistake5(

OUT error VARCHAR(5))

BEGIN

DECLARE CONTINUE HANDLER FOR SQLWARNING,NOT FOUND,SQLEXCEPTION

---》错误是1开头的赋给SQLWARNING,2开头的NOT FOUND,其他给SQLEXCEPTION

SET error = 'xxxxx';

INSERT INTO teams VALUES(2,27,'third');

END$$

DELIMITER ;

mysql> call small_mistake5(@a);

Query OK, 0 rows affected (0.00 sec)

mysql> select @a;

+-------+

| @a |

+-------+

| xxxxx |

+-------+

1 row in set (0.00 sec)

===忽略一个错误:

忽略一个条件

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;

–》碰到1开头的就过。

五、异常处理嵌套问题

例子1:增加程序的可读性。

DELIMITER $$

CREATE PROCEDURE small_mistake6(

OUT error VARCHAR(5))

BEGIN

DECLARE non_unique CONDITION FOR SQLSTATE '23000';

DECLARE CONTINUE HANDLER FOR non_unique

begin

SET error = '23000';

select error;

end;

INSERT INTO TEAMS VALUES(2,27,'third');

END$$

DELIMITER ;

mysql> call small_mistake6(@error);

+-------+

| error |

+-------+

| 23000 |

+-------+

1 row in set (0.01 sec)

例子2:异常处理的嵌套

DELIMITER $$

CREATE PROCEDURE small_mistake7()

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '23000'

SET @processed = 100;

BEGIN

DECLARE CONTINUE HANDLER FOR SQLSTATE '21000'

SET @processed = 200;

INSERT INTO TEAMS VALUES(2,27,'third');

--》出错,假设能被内层的捕获,就执行200;若不能被内层捕获,内层的begin...end就废了,就执行外层100

END;

END$$

DELIMITER ;

mysql> call small_mistake7;

Query OK, 0 rows affected (0.00 sec)

mysql> select @processed;

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

| @processed |

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

| 100 |

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

1 row in set (0.00 sec)

====小结

当有多层begin…end的时候,最好每层都有自己完善的异常处理。自己异常,自己这层去处理。

六、游标 CURSOR

游标:处理结果集。多行多列

====例子1:

DELIMITER $$

CREATE PROCEDURE number_of_players(

OUT pnumber INTEGER

)

BEGIN

DECLARE a_playerno INTEGER; --》变量1

DECLARE FOUND BOOLEAN DEFAULT TRUE; --》变量2

DECLARE c_players CURSOR FOR --》声明游标(将游标和sql语句关联起来)

SELECT playerno FROM PLAYERS;

DECLARE CONTINUE HANDLER FOR NOT FOUND --》异常处理,所有的以2开头的错误

SET FOUND = FALSE; --》异常处理后FOUND变为false

SET pnumber = 0;

OPEN c_players; --》打开游标(将游标和结果集联系起来)

FETCH c_players INTO a_playerno; --》fetch...into相当于select into

WHILE FOUND DO

SET pnumber = pnumber + 1;

FETCH c_players INTO a_playerno; --》循环中的fetch...into,依次指向结果集的一个

END WHILE;

CLOSE c_players;

END$$

DELIMITER ;

mysql> call number_of_players(@pnumber);

Query OK, 0 rows affected (0.00 sec)

mysql> select @pnumber;

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

| @pnumber |

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

| 14 |

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

1 row in set (0.00 sec)

游标处理方式小结:

定义游标:将一个游标和一个select进行关联;

打开游标:将一个游标和一个结果集关联,执行了select;

获取游标(获取结果集):需要使用循环进行游标的获取。

{注意:当获取到最后一个结果集时,再次执行循环的时候,会报错,这个错误以2开头,

这个时候,需要定义一个对2开头的错误的捕获:

DECLARE CONTINUE HANDLER FOR NOT FOUND

SET FOUND = FALSE; }

关闭游标:结果集消失

资源释放。

七、存储过程权限问题

mysql>select ROUTINE_NAME,ROUTINE_SCHEMA,ROUTINE_TYPE from ROUTINES where ROUTINE_SCHEMA in('test','TENNIS');

GRANT EXECUTE --》授予执行权限

ON PROCEDURE number_penalties

TO 'u1'@'%';

[root@mysqlstudy ~]# mysql -uu1 -p12345678

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 7

Server version: 5.7.10 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use TENNIS;

Database changed

mysql> call number_penalties(44,@pnumber);

Query OK, 0 rows affected (0.01 sec)

mysql> select @pnumber;

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

| @pnumber |

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

| 3 |

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

1 row in set (0.00 sec)

mysql游标遍历中sql语句出现异常_MySQL中的异常处理,游标相关推荐

  1. mysql多表查询sql语句怎么写_MySQL基本SQL语句之单表查询、多表查询和子查询

    一.简单查询: 基本语法: SELECT * FROM tb_name;查询全部 SELECT field1,field2 FROM tb_name; 投影 SELECT [DISTINCT] * F ...

  2. mysql更新多表sql语句怎么写_MySQL多表updatesql语句总结

    MySQL 多表 update 有几种不同的写法.假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是 MySQL 多表 update 有几种不同的写法. ...

  3. mysql修改数据的sql语句怎么写_MySQL数据库修改数据语句的简单用法

    1.insert语句 MySQL的insert语句有两种方式: INSERT INTO tablename() VALUES(列值); INSERT INTO tablename SET column ...

  4. 【大话Mysql面试】-常见SQL语句书写

    [大话Mysql面试]-常见SQL语句书写 4.1 SQL语句主要分为哪几类? 数据定义语言DDL(Data Defination Language):主要为create drop alter等操作, ...

  5. mysql sql先后执行_MySQL中SQL语句执行顺序

    (7) SELECT (8) DISTINCT (1) FROM (3) JOIN (2) ON (4) WHERE (5) GROUP BY (6) HAVING (9) ORDER BY (10) ...

  6. Mysql中SQL语句不使用索引的情况

    Mysql中SQL语句不使用索引的情况 MySQL查询不使用索引汇总 众所周知,增加索引是提高查询速度的有效途径,但是很多时候,即使增加了索引,查询仍然不使用索引,这种情况严重影响性能,这里就简单总结 ...

  7. mysql数据库语句分类_细数MySQL中SQL语句的分类

    1:数据定义语言(DDL) 用于创建.修改.和删除数据库内的数据结构,如:1:创建和删除数据库(CREATE DATABASE || DROP  DATABASE):2:创建.修改.重命名.删除表(C ...

  8. MySql安装教程与HeidiSQL管理工具使用方法、HeidiSQL中SQL语句使用(六)

    文章目录 Mysql下载路径 Mysql管理工具--HeidiSQL下载 安装完成之后可以进行sql语句测试编辑 设置主键自增长 HeidiSQL中SQL语句使用 创建数据库 删除与创建表 像表中插入 ...

  9. 实现分页统计记录总数时: sql语句的异常

    实现分页统计记录总数时: sql语句的异常 sql: select count(n) from dblog n where n.deleteflag=0: 这句话在jdbc 环境和 mysql自带查询 ...

最新文章

  1. 【最新综述】轻量级神经网络架构综述
  2. 22021年江苏高考成绩查询,江苏高考成绩查询系统入口
  3. 【java】动态高并发时为什么推荐重入锁而不是Synchronized?
  4. jQuery Event.delegateTarget 属性详解
  5. 【原】React中,map出来的元素添加事件无法使用
  6. 软件分享 kemulator lite
  7. mac 系统搭建web服务器,MAC OS 如何搭建本地webserver
  8. 老外网络语言缩写总结
  9. Cluster status reports MDSs behind on trimming
  10. 形象理解计算机网络里的各种抽象概念
  11. 让 CAS 5.1.8 支持http,解决未认证授权服务错误提示问题
  12. zk选举机制和分布式一致性原理
  13. SQL Inject
  14. 推荐几款渗透测试常用的脚本(记得收藏)
  15. SpringMVC @RequestBody问题:Unrecognized field , not marked as ignorable
  16. 2022最新苹果iOS证书制作教程
  17. 【GoodERP专题】第一章 GoodERP应用专题之good_expense 费用报销 的使用
  18. 《三易通服装进销存软件》项目研发阶段性总结
  19. 隐私计算开源平台Rosetta部署分享
  20. 还在为手机运行内存RAM剩余多少烦恼吗?

热门文章

  1. springmvc异常处理器
  2. 基于jQuery/zepto的单页应用(SPA)搭建方案
  3. 一些常用的meta标签及其作用
  4. scala shuffle
  5. 记忆化搜索 codevs 2241 排序二叉树
  6. 年龄大了学Java是爱好还是转型?
  7. 定制自己的Windows CE 5.0 ARM中文模拟器(转)
  8. 牛客15499 Jxc军训(快速幂,逆元)
  9. 仰望星空后,更将脚踏实地!
  10. python logging模块的作用及应用场景_Python logging模块原理解析及应用