您好,欢迎访问一九零五行业门户网

MySQL5.7的错误堆栈缓冲_MySQL

什么是错误缓冲堆栈呢? 举个很简单的例子,比如执行下面一条语句:
mysql> insert into t_datetime values(2,'4','5'); error 1292 (22007): incorrect datetime value: '4' for column 'log_time' at row 1
上面1292这个代码指示的错误信息保存在哪里呢? 就保存在错误缓冲堆栈, 在mysql里面叫 diagnostics area。 关于这个概念,一直在mysql5.7才得到确定的更新。
在mysql5.5之前,想要得到这块区域的数据,就只能通过c的api来获取,从sql层面是无法检索到的。mysql5.5 先推出了这个概念。
在mysql5.6发布后,不但可以检索这块区域,而且还可以重新封装,得到我们想要的数据。但是这块区域依然是只能保存一次错误代码,很容易被重置。
在mysql5.7发布后,可以更加容易的检索这块区域,而且把这里的数据放到一个stack里,重置的条件更加宽松。以下举例子来说明。
示例表结构如下,
create table `t_datetime` ( `id` int(11) not null, `log_time` timestamp not null default current_timestamp on update current_timestamp, `end_time` datetime not null, primary key (`id`) ) engine=innodb default charset=utf8;
用来记录错误数据的日志表。
create table tb_log (errorno int,errortext text,error_timestamp datetime);
在mysql5.6环境下,我要这样写一段繁杂的代码来获取错误信息。
delimiter $$ use `new_feature`$$ drop procedure if exists `sp_do_insert`$$ create definer=`root`@`localhost` procedure `sp_do_insert`( in f_id int, in f_log_time varchar(255), in f_end_time varchar(255) ) begin declare done1 tinyint default 0; -- 保存是否发生异常的布尔值。 declare i tinyint default 1; declare v_errcount int default 0; -- 获取一次错误数据条数 declare v_errno int default 0; -- 获取错误代码 declare v_msg text; -- 获取错误详细信息 declare continue handler for sqlexception -- 定义一个异常处理块 begin set done1 = 1; -- 发生异常,设置为1. get diagnostics v_errcount = number; set v_msg = ''; while i <= v_errcount do get diagnostics condition i v_errno = mysql_errno, v_msg = message_text; set @stmt = concat('select ',v_errno,',"',v_msg,'","',now(),'" into @errno',i,',@msg',i,', @log_timestamp',i,';'); prepare s1 from @stmt; execute s1; set i = i + 1; end while; drop prepare s1; end; insert into t_datetime (id,log_time,end_time) values(f_id,f_log_time,f_end_time); if done1 = 1 then -- 把错误数据记录到表tb_log里。 set i = 1; while i <= v_errcount do set @stmt = concat('insert into tb_log '); set @stmt = concat(@stmt,' select @errno',i,',@msg',i,',@log_timestamp'); prepare s1 from @stmt; execute s1; set i = i + 1; end while; drop prepare s1; end if; end$$ delimiter ;
mysql5.7发布后,现在可以精简我的代码了。
delimiter $$ use `new_feature`$$ drop procedure if exists `sp_do_insert`$$ create definer=`root`@`localhost` procedure `sp_do_insert`( in f_id int, in f_log_time varchar(255), in f_end_time varchar(255) ) begin declare i tinyint default 1; declare v_errcount int default 0; -- 获取一次错误数据条数 declare v_errno int default 0; -- 获取错误代码 declare v_msg text; -- 获取错误详细信息 declare continue handler for sqlexception -- 定义一个异常处理块 begin get stacked diagnostics v_errcount = number; while i <= v_errcount do get stacked diagnostics condition i -- 把错误数据分别保存在变量里 v_errno = mysql_errno, v_msg = message_text; insert into tb_log values (v_errno,v_msg,now()); set i = i + 1; end while; end; insert into t_datetime (id,log_time,end_time) values(f_id,f_log_time,f_end_time); end$$ delimiter ;
现在来执行下:
mysql> call sp_do_insert(2,'4','5');
query ok, 1 row affected (0.01 sec)
来检索表tb_log的数据。
mysql> select * from tb_log\g *************************** 1. row *************************** errorno: 1265 errortext: data truncated for column 'log_time' at row 1 error_timestamp: 2015-11-17 11:53:10 *************************** 2. row *************************** errorno: 1265 errortext: data truncated for column 'end_time' at row 1 error_timestamp: 2015-11-17 11:53:10 *************************** 3. row *************************** errorno: 1062 errortext: duplicate entry '2' for key 'primary' error_timestamp: 2015-11-17 11:53:10 3 rows in set (0.00 sec)
总结下, 如果先用到diagnostics area, 最好是在存储过程里面写代码封装sql。
以上就是mysql5.7的错误堆栈缓冲_mysql的内容。
其它类似信息

推荐信息