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架构套接字) 数据库管理软件分类 ...
随机推荐
- ORM字段操作
django orm 建表字段 在django modle 中,我们定义的类,他的对象就是数据库表中的一行数据!!! django orm 基础 一:modle的各个字段: 在python中以code ...
- PAT Basic 1026
1026 程序运行时间 (15 分) 要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗 ...
- js小题目(持续更新)
总是感觉之前做过的问题很久没碰的话就会忘掉,于是打算专门开一个记录小题目的随笔当题典用. 目录 五种主要数据类型进行值复制 数组去重 数组去重并计数 实现clone()方法,对五种主要数据类型进行值复 ...
- nested exception is java.lang.ClassNotFoundException
当出现nested exception is java.lang.ClassNotFoundException这个异常的时候,首先排查类是否存在.如果存在,是maven项目的话,clean.insta ...
- Node_初步了解(2)
1. windown下 npm 升级: npm install npm -g 2. Node.js事件驱动模型:设计模型——观察者模型. 3. node.js全局变量:global 4. node.j ...
- sql 索引笔记--索引组织结构
非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点: 基础表的数据行不按非聚集键的顺序排序和存储. 非聚集索引的叶层是由索引页而不是由数据页组成. 既可以使用聚集索引来为表或视 ...
- 完美解决C#Webbrowser控件设置Cookie问题
完美解决C#Webbrowser控件设置Cookie问题由于个人项目需求,需要把从抓包里面的Cookie数据写入到webbrowser空控件里,经过百度白百般折腾,结果还是失败,搜索到的答案基本上都是 ...
- mac下host配置 + mac修改了环境变量却不生效:zsh: command not found: xxx
https://blog.csdn.net/hlllmr1314/article/details/52228672 在/etc/profile中配置了go语言环境变量: export GOROOT=/ ...
- python3 HTTP Error 403:Forbidden
问题描述初学python,在用python中的urllib.request.urlopen()和urllib.request.urlretrieve方法打开网页时,有些网站会抛出异常: HTTP Er ...
- jquery append 和appendTo
原文: https://www.cnblogs.com/stitchgogo/p/5721551.html ---------------------------------------------- ...