什麼是錯誤緩衝堆疊呢? 舉個很簡單的例子,比如執行下面一條語句:
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
doget 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
doset @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
doget 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 insert into t datetime values 2,4 5 error 1292 22007 incorrect datetime value 4 for column log time at row 1 上面1...
mysql5 7學習 mysql 5 7 學習
mysql uroot proot mysql5.7 mysql.user表沒有password欄位改 authentication string 一.建立使用者 命令 create user username host identified by password 例子 create user d...
mysql57是什麼 關於mysql57的詳細介紹
簡介 php7 mysql57 nginx19 on ubuntu 1404 本文 前段時間php公升級到了7.0版本,據說很牛叉,比如效能較5.6提公升兩倍,記憶體占用低之類的,後來又看微博上說等到7.0.1才穩定。果不其然,很快就公升級了,最近才有時間折騰一下,在這裡做個總結。環境 1核1g主機...