MySQL-[SIGNAL/RESIGNAL/GET DIAGNOSTICS]的使用
最近在做 SQL Server 到 MySQL 的迁移(migration),相较于对表和数据的迁移,最令人犯难的还是在功能性存储过程脚本的改写转换(convert),虽说 MySQL 如今是蓬勃发展,不断的更新迭代的优化,但是在存储过程等脚本方面与 Oracle、SQL Server 相比,个人感觉是有所欠缺的,无论是灵活性还是实用性,有时真的是很难达到自己想要的效果,或许这就是为什么存储过程在 MySQL 中使用较少的原因吧……
承接上一篇关于MySQL的异常处理,继续异常处理的扩展性用法:
异常处理语句:
3、SIGNAL …
一、常规声明的异常处理
1、条件声明
DECLARE condition_name CONDITION FOR condition_value
condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
}
condition_name:标准的变量命名;
condition_value:SQLSTATE 值或者 MySQL 自身的 ERROR CODE ;
注:单独的 condition 语句不能直接运行,只能作为【条件处理】的一部分。
2、条件处理
DECLARE handler_action HANDLER
FOR condition_value [, condition_value] ...
statement handler_action: {
CONTINUE
| EXIT
| UNDO
} condition_value: {
mysql_error_code
| SQLSTATE [VALUE] sqlstate_value
| condition_name
| SQLWARNING
| NOT FOUND
| SQLEXCEPTION
}
handler_action:代表处理的动作,常用的是继续(CONTIUE)和直接退出(EXIT);
condition_value:异常处理捕获条件或情况,包括【条件声明】里的 SQLSTATE, MYSQL EEROR CODE, condition_name 以及范围混淆的其他两种;
注:SQLWARNING、SQLEXCEPTION、NOT FOUND 表示任何不存在的 WARNING 或者 ERROR。
mysql> DESC tab7;
ERROR 1146 (42S02): Table 'TestDB.tab7' doesn't exist DELIMITER //
CREATE PROCEDURE PROC_1()
BEGIN
DECLARE CONTINUE HANDLER FOR 1146
BEGIN
-- body of handler
END; DECLARE not_exist_table CONDITION FOR 1146;
DECLARE CONTINUE HANDLER FOR not_exist_table
BEGIN
-- body of handler
END; DECLARE not_exist_table CONDITION FOR SQLSTATE '42S02';
DECLARE CONTINUE HANDLER FOR not_exist_table
BEGIN
-- body of handler
END;
END //
DELIMITER ;
二、SIGNAL 与 RESIGNAL
SIGNAL 与 RESIGNAL 可以通过自定义伪装系统的错误信息以及代码,刷新当前警告缓冲区域。
1、SIGNAL
SIGNAL是“返回”错误的方法,向处理程序,应用程序的外部部分或客户端提供错误信息。
此外,它还可以控制错误的特征(错误号,SQLSTATE值,消息)。 如果没有SIGNAL,则必须采用诸如故意引用不存在的表之类的解决方法来导致例程返回错误。
SIGNAL condition_value
[SET signal_information_item
[, signal_information_item] ...] condition_value: {
SQLSTATE [VALUE] sqlstate_value
| condition_name
} signal_information_item:
condition_information_item_name = simple_value_specification condition_information_item_name: {
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
}
2、RESIGNAL
同样的,RESIGNAL 也可以异常处理并返回错误信息。
RESIGNAL [condition_value]
[SET signal_information_item
[, signal_information_item] ...] condition_value: {
SQLSTATE [VALUE] sqlstate_value
| condition_name
} signal_information_item:
condition_information_item_name = simple_value_specification condition_information_item_name: {
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
}
通过对比 SIGNAL 与 RESIGNAL 的语法,在使用 SIGNAL 方法的时候必须指定 condition_value ,也就是说其不能单独使用,需要先定义异常处理,可以在存储过程中的任何位置使用 SIGNAL 语句。
而 RESIGNAL 可以省略RESIGNAL语句的所有属性,甚至可以省略SQLSTATE值,但必须在错误或警告处理程序中使用 RESIGNAL 语句,否则将收到一条错误消息,指出“RESIGNAL when handler is not active”。如果单独使用RESIGNAL语句,则所有属性与传递给条件处理程序的属性相同。
3、常见对比使用实例
DELIMITER //
CREATE PROCEDURE `test_proc`(var1 int,var2 int)
BEGIN
declare ErrorMessage varchar(255) ;
-- SIGNAL Declarations
declare EXP_CONDITION condition for sqlstate 'EX000' ;
declare exit handler for sqlstate 'EX000' begin
signal EXP_CONDITION set message_text = ErrorMessage ;
end ;
-- RESIGNAL Declarations
declare exit handler for sqlstate '42S02' begin
resignal set message_text = 'Unknown tables appear in the process body.' ;
end ;
-- Processing
if( var1 <> var2 ) then
set ErrorMessage = 'The first number input does not equal the second number.' ;
signal EXP_CONDITION set message_text = ErrorMessage ;
end if ;
select * from xxx ; -- unknow table xxx
END //
DELIMITER ;
mysql> call test_proc(1,1);
ERROR 1146 (42S02): Unknown tables appear in the process body.
mysql> call test_proc(1,2);
ERROR 1644 (EX000): The first number input does not equal the second number.
推荐使用 SIGNAL,灵活随机,在定义好后即可将 SIGNAL 语句放到任何你想放的地方进行判断预警处理。
三、GET DIAGNOSTICS
5.6开始支持的语法,从而获取错误缓冲区的内容,然后把这些内容输出到不同范围域的变量里,以便后续灵活操作处理。
GET [CURRENT | STACKED] DIAGNOSTICS
{
statement_information_item
[, statement_information_item] ...
| CONDITION condition_number
condition_information_item
[, condition_information_item] ...
} statement_information_item:
target = statement_information_item_name condition_information_item:
target = condition_information_item_name statement_information_item_name:
NUMBER
| ROW_COUNT condition_information_item_name: {
CLASS_ORIGIN
| SUBCLASS_ORIGIN
| RETURNED_SQLSTATE
| MESSAGE_TEXT
| MYSQL_ERRNO
| CONSTRAINT_CATALOG
| CONSTRAINT_SCHEMA
| CONSTRAINT_NAME
| CATALOG_NAME
| SCHEMA_NAME
| TABLE_NAME
| COLUMN_NAME
| CURSOR_NAME
}
statement_information_item:statment 执行情况信息捕获反馈,包括 NUMBER、ROW_COUNT;
condition_information_item:捕获异常情况信息;
当条件发生,可以通过变量去接收条件项目信息,但也不是说有的 MySQL 都会进行填充赋值,也会出现空值的(例如:SCHEMA_NAME and TABLE_NAME is null when drop table)。
mysql> delete from t5;
Query OK, 3 rows affected (0.04 sec) mysql> GET DIAGNOSTICS @p3 = NUMBER, @p4 = ROW_COUNT;
Query OK, 0 rows affected (0.00 sec) mysql> select @p3,@p4;
+------+------+
| @p3 | @p4 |
+------+------+
| 0 | 3 |
+------+------+
1 row in set (0.00 sec) mysql> drop table xxx;
ERROR 1051 (42S02): Unknown table 'TestDB.xxx'
mysql> show warnings; -- or show error
+-------+------+----------------------------+
| Level | Code | Message |
+-------+------+----------------------------+
| Error | 1051 | Unknown table 'TestDB.xxx' |
+-------+------+----------------------------+
1 row in set (0.00 sec) mysql> GET DIAGNOSTICS CONDITION 1
-> @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT;
Query OK, 0 rows affected (0.00 sec) mysql> select @p1,@p2;
+-------+----------------------------+
| @p1 | @p2 |
+-------+----------------------------+
| 42S02 | Unknown table 'TestDB.xxx' |
+-------+----------------------------+
1 row in set (0.00 sec)
注:个人认为,因为使用 GET DIAGNOSTICS 略有些鸡肋,使用选择上更多的会是用 SIGNAL 语句进行异常处理,所以在此不做深究 GET DIAGNOSTICS 的使用。
MySQL-[SIGNAL/RESIGNAL/GET DIAGNOSTICS]的使用的更多相关文章
- Raising Error Conditions with MySQL SIGNAL / RESIGNAL Statements
http://www.mysqltutorial.org/mysql-signal-resignal/ Summary: in this tutorial, you will learn how to ...
- MySQL存储过程整理
MySQL存储过程 2018-08-15 23:00:06 1.存储过程介绍 (1) 定义:存储过程是存储在数据库目录中的一段声明性SQL语句. 触发器,其他存储过程以及java,python,ph ...
- (转)mysql各个主要版本之间的差异
原文:http://blog.csdn.net/z1988316/article/details/8095407 一.各版本的常用命令差异 show innodb status\G mysql-5 ...
- MySQL 4.1-5.0-5.1-5.5-5.6各版本的主要区别
各版本的一些命令差异: show innodb status\G mysql-5.1 show engines innodb status\G mysql-5.5 关于grant授权 mysql ...
- MYSQL的历史
MYSQL的历史 见证MySQL发展历程 各分支版本溯源 http://tech.it168.com/a2012/0621/1363/000001363446.shtml [IT168 技术]毫无疑问 ...
- MySql与MariaDB由来与历程
MySQL数据库 MySQL数据库是一个关系型数据库管理系统,由瑞典MySQL AB公司开发.MySQL是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这 ...
- 【Mysql】Mysql 各个版本区别
一.Mysql 各个版本区别: 1.MySQL Community Server 社区版本,开源免费,但不提供官方技术支持.这也是我们通常用的MySQL的版本.根据不同的操作系统平台细分为多个版本 2 ...
- 学习笔记:The Best of MySQL Forum
http://mysql.rjweb.org/bestof.html I have tagged many of the better forum threads. 'Better' is based ...
- mysql数据库( 基础篇加破解)
1.数据库(Database,DB)是按照数据结构来组织.存储和管理数据的,并且是建立在计算机存储设备上的仓库 2.什么是数据库:(用来存储数据的仓库) 数据库:(cs架构套接字) 数据库管理软件分类 ...
随机推荐
- 超详细 Spring @RequestMapping 注解使用技巧
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一.这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上. 在这篇文章中,你将会看到 @R ...
- Python高级有关的题目
1,copy模块 from copy import deepcopy dic = {} list = [] for i in range(10): dic["num"] = i i ...
- django之视图获取用户请求相关信息以及请求头
def index(request): print(type(request)) print(request.environ['HTTP_USER_AGENT'])#字典格式 print(reques ...
- web (Servlet)
1.如果你文档新建的出现很多红色的小擦擦出错 这样做
- Java知识回顾 (9) 同步、异步IO
一.基本概念 同步和异步: 同步和异步是针对应用程序和内核的交互而言的. 同步指的是用户进程触发IO 操作并等待或者轮询的去查看IO 操作是否就绪: 而异步是指用户进程触发IO 操作以后便开始做自己的 ...
- mui 打开外网链接返回的正姿势!
我们的返回分两种: 一:按返回按钮只能返回上一页 二:向右滑动一步返回app的面页
- 硬件工程师必会电路模块之MOS管应用
实际工程应用中常用的MOS管电路(以笔记本主板经典电路为例): 学到实际系统中用到的开关电路模块以及MOS管非常重要的隔离电路(结合IIC的数据手册和笔记本主板应用电路): MOS管寄生体二极管,极性 ...
- SpringBoot项目接口第一次访问慢的问题
SpringBoot的接口第一次访问都很慢,通过日志可以发现,dispatcherServlet不是一开始就加载的,有访问才开始加载的,即懒加载. 2019-01-25 15:23:46.264 IN ...
- html5学习笔记2——新元素
一:H5的改变 <canvas> 新元素 标签 描述 <canvas> 标签定义图形,比如图表和其他图像.该标签基于 JavaScript 的绘图 API 新多媒体元素 标签 ...
- XCode各种问题
2018.07.10 1.clang: warning: libstdc++ is deprecated; move to libc++ [-Wdeprecated] 2.2018.07.29 海康 ...