【オリジナル】mysqlエラーバッファスタック
エラーバッファスタックとは?簡単な例を挙げます.たとえば、次の文を実行します.
上の1292というコードが示すエラー情報はどこに保存されていますか?エラーバッファスタックに保存され、MySQLではDIAGNOSTICS AREAと呼ばれます.この概念について、ずっとMySQL 5にいます.7で確定した更新が得られました.
MySQL 5.5以前は、このエリアのデータを取得するには、CのAPIでしか取得できず、SQLレベルでは検索できませんでした.MySQL5.5まずこの概念を発表した.
MySQL 5.6リリース後、この領域を検索するだけでなく、再パッケージして、私たちが望んでいるデータを得ることができます.しかし、この領域は依然としてエラーコードを1回しか保存できず、リセットされやすい.
MySQL 5.7リリース後、このエリアをより簡単に検索でき、ここのデータを1つのSTACKに入れることで、リセットの条件がより緩和されます.以下に例を挙げて説明する.
表の構成例は次のとおりです.
エラー・データを記録するためのログ・テーブル.
MySQL 5.6環境では、このように複雑なコードを書いてエラー情報を取得します.
MySQL5.7リリース後、私のコードを簡素化できます.
次に、
テーブルtbを取得するlogのデータ.
まとめて、DIAGNOSTICS AREAを先に使用する場合は、ストレージプロセスにSQLをコードパッケージするように書くのが望ましい.
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と呼ばれます.この概念について、ずっとMySQL 5にいます.7で確定した更新が得られました.
MySQL 5.5以前は、このエリアのデータを取得するには、CのAPIでしか取得できず、SQLレベルでは検索できませんでした.MySQL5.5まずこの概念を発表した.
MySQL 5.6リリース後、この領域を検索するだけでなく、再パッケージして、私たちが望んでいるデータを得ることができます.しかし、この領域は依然としてエラーコードを1回しか保存できず、リセットされやすい.
MySQL 5.7リリース後、このエリアをより簡単に検索でき、ここのデータを1つの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);
MySQL 5.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をコードパッケージするように書くのが望ましい.