mysql是棧 原創 mysql 錯誤緩衝堆疊

2021-10-17 15:41:10 字數 4215 閱讀 4220

什麼是錯誤緩衝堆疊呢? 舉個很簡單的例子,比如執行下面一條語句: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。

mysql顯錯注入 MySQL注入之顯錯注入

庫 就是一堆表組成的資料集合 資料庫裡自帶的系統庫 information schema information schema裡columns表裡存著所有欄位名 information schema裡schemata表裡存著所有庫名 information schema裡tables表裡存著所有表名...

MySQL顯錯注入

updatexml xml target,xpath expr,new xml 該函式將xml標記xml target的給定片段的單個部分替換為新的xml片段new xml,然後返回更改後的xml。被替換的xml target部分與使用者提供的xpath表示式xpath expr匹配。說白了,就是用...

mysql連線失敗HikariPool錯誤

com.zaxxer.hikari.pool.hikaripool hikaripool 1 exception during pool initialization.引起程式無法啟動的問題是 com.zaxxer.hikari.pool.hikaripool 沒能成功被 spring 建立,原因是...