1. 程式人生 > >MySQL5.7 的 錯誤堆疊緩衝

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



上面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> INSERT INTO t_datetime VALUES(2,'4','5');ERROR 1292 (22007): Incorrect datetime value: '4' for c

MySQL5.7錯誤堆棧緩沖

prepare ont rac 存儲過程 堆棧 table charset 語句 lar 什麽是錯誤緩沖堆棧呢? 舉個非常簡單的樣例,比方運行以下一條語句:mysql> INSERT INTO t_datetime VALUES(2,‘4‘,‘5‘);ERROR

mysql5.7 啟動報發生系統錯誤2

media font 有一個 ins baidu ref aec 桌面 ima 1. http://dev.mysql.com/downloads/mysql/ 下載mysql5.7 zip包 2. 下載好後解壓文件,解壓的內容如圖,您可以把內容

mysql5.7安裝的實踐過程與錯誤排查參考

dem 情況下 rod 添加 first row sco assume export 了解LAMP和安裝mysql服務 LAMP=Linux+Apache+Mysql+PHP四種組成的一個系統Apache和php必須在一臺服務器上才可使用,mysql可以通過網絡方式來提供服

Mysql5.7.20使用group by查詢(select *)時出現錯誤--修改sql mode

Mysql5.7.20使用group by查詢(select *)時出現錯誤--修改sql mode 使用select * from 表 group by 欄位 時報錯      錯誤資訊說明:   1055 - Expression #1 of SELECT list

Mysql5.7錯誤日誌中最常見的note級別日誌解釋

在使用mysql5.7的時候,發現了不少在mysql5.6上不曾見過的日誌,級別為note, 最常見的note日誌以下三種,下面我們來逐個解釋。 第一種,Aborted connection . 如上圖,資訊如下: 2016-03-17T14:44:24.102542Z 59 [Not

mysql5.7 新建使用者1396錯誤和1819錯誤

去掉密碼規則 vim /etc/my.cnf 在my.cnf中加上如下這句話 去掉密碼校驗規則解決1819 問題 validate_password=off 去掉之後記得重啟mysql(我用的centos6 ,好難用 不過客戶喜歡,沒得辦法) 重啟mysql serv

【MySQL】MySQL5.7 匯入時報“cannot create a JSON value from a string with CHARACTER SET 'binary'.”錯誤的解決辦法

json是mysql 5.7版本才新增的資料型別,用mysql-front 6.0匯出時json欄位會自動轉換成十六進位制“X’7B226……227D”,而不是json格式。 所以在匯入時就會報錯。 我的解決辦法: 1.用notepad++等文字編輯器開啟.sql檔案;

mysql5.7的密碼修改錯誤問題:ERROR 1054 (42S22): Unknown column 'password' in 'field list'的解決

本意向修改一個使用者的密碼,網上搜到的命令為如下 1 mysql> update user set password=password(“新密碼”) where user=”使用者名稱”; 執行後報錯  E

mysql5.7版本之後安裝成功後,服務無法啟動,沒有報告任何錯誤的解決辦法。

原因多出在手動建立data目錄。 5.7版本及以前可以通過新建一個my.ini檔案,然後輸入一下程式碼即可按步驟成功啟動: [client] port=3306 default-character-set=utf8 [mysqld]  # 設定為自己MYSQL的安裝目錄&n

開發工具MySQL-MySQL5.7.20服務端圖文安裝教程(附:錯誤解決方案)

一、官網地址 https://www.mysql.com/downloads/ 二、安裝(windows安裝包安裝) 1.點選mysql-installer-community-5.7.20.msi安裝 2.點選點“接受”,Next 3.選“Server Only”,

在win10下安裝mysql5.7常見錯誤解決

1.錯誤:服務正在啟動,服務無法啟動 解決方法: 在cmd下輸入命令 mysql –initialize命令初始化 再使用 net start mysql命令即可開啟mysql 2.錯誤:ERR

mysql5.7.24 安裝時出現1042錯誤

安裝mysql5.7.24的installer版本的時候最後應用配置這裡出現以下錯誤 看了下log 解決過程: 看了網上的操作,先是在hosts檔案中# 127.0.0.0.1 :localho

MySQL5.7.14執行SQL時出現1055錯誤

錯誤: [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column ‘information_schema.

Qt5.9連線MySql5.7.17錯誤解決辦法(錯誤提示:QMYSQL driver not loaded)

我用Qt5.9新建一個Console控制檯程式,用Qt5.9Console控制檯測試連線MySql5.7.17資料庫時,出現MySql資料庫驅動不可用,具體的程式碼和錯誤如下所示:1.1程式碼如下:(記得在.pro問價裡面新增QT+=sql)#include<QCore

ubuntu上編譯安裝mysql5.7.x【多次錯誤之後總結的方法】

1.進入mysql官網->Downloads->MySQL Community Edition->MySQL Community Server->Select Platform

mysql5.7.x服務無法啟動,服務沒有報告任何錯誤問題

在官網下的最新版免安裝zip的mysql5.7.12,解壓後用管理員身份執行cmd進入bin目錄下,用net start mysql提示服務無法啟動 實際上這個版本的mysql檔案解壓後是沒有da

Mysql5.7.17安裝後錯誤日誌中有警告

  警告1: secure_file_priv 配置項對資料匯入匯出的影響 1、限制mysqld 不允許匯入 | 匯出  mysqld --secure_file_prive=null MySQL [ztjy]> select * from info_posts li

mysql5.7高版本加載低版本sql文件,時間不能為0000-00-00格式錯誤

sele global %s ike ssi invalid bsp mysql5.7 for 錯誤代碼:ERROR 1067 (42000): Invalid default value for 解決方式 1. show session variable

MySQL5.7.25報1055錯誤解決方案

table for tex mysqld centos nag fff ati http 基本信息:  系統一:CentOS7.5 + mysql5.7.25  系統二:win10 + mysql5.7.25解壓縮版 數據庫表結構如下: 對MySql進行操作時報以下