• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

【原创】mysql 错误缓冲堆栈_MySQL

mysql 搞代码 4年前 (2022-01-09) 16次浏览 已收录 0个评论

什么是错误缓冲堆栈呢? 举个很简单的例子,比如执行下面一条语句:

mysql>INSERTINTOt_datetimeVALUES(2,'4','5');ERROR1292(22007):Incorrectdatetimevalue:'4'forcolumn'log_time'atrow1

上面1292这本文来源gaodai$ma#com搞$代*码6网个代码指示的错误信息保存在哪里呢? 就保存在错误缓冲堆栈, 在MySQL里面叫 DIAGNOSTICS AREA。 关于这个概念,一直在MySQL5.7才得到确定的更新。

在MySQL5.5之前,想要得到这块区域的数据,就只能通过C的API来获取,从SQL层面是无法检索到的。MySQL5.5 先推出了这个概念。

在MySQL5.6发布后,不但可以检索这块区域,而且还可以重新封装,得到我们想要的数据。但是这块区域依然是只能保存一次错误代码,很容易被重置。

在MySQL5.7发布后,可以更加容易的检索这块区域,而且把这里的数据放到一个STACK里,重置的条件更加宽松。以下举例子来说明。

示例表结构如下,

CREATETABLE`t_datetime`(`id`int(11)NOTNULL,`log_time`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,`end_time`datetimeNOTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8;

用来记录错误数据的日志表。

CREATETABLEtb_log(errornoint,errortextTEXT,error_timestampDATETIME);

在MySQL5.6环境下,我要这样写一段繁杂的代码来获取错误信息。

DELIMITER$$USE`new_feature`$$DROPPROCEDUREIFEXISTS`sp_do_insert`$$CREATEDEFINER=`root`@`localhost`PROCEDURE`sp_do_insert`(INf_idINT,INf_log_timeVARCHAR(255),INf_end_timeVARCHAR(255))BEGINDECLAREdone1TINYINTDEFAULT0;--保存是否发生异常的布尔值。DECLAREiTINYINTDEFAULT1;DECLAREv_errcountINTDEFAULT0;--获取一次错误数据条数DECLAREv_errnoINTDEFAULT0;--获取错误代码DECLAREv_msgTEXT;--获取错误详细信息DECLARECONTINUEHANDLERFORSQLEXCEPTION--定义一个异常处理块BEGINSETdone1=1;--发生异常,设置为1.getdiagnosticsv_errcount=number;SETv_msg='';WHILEi<=v_errcountDOGETDIAGNOSTICSCONDITIONiv_errno=MYSQL_ERRNO,v_msg=MESSAGE_TEXT;SET@stmt=CONCAT('select',v_errno,',"',v_msg,'","',NOW(),'"into@errno',i,',@msg',i,',@log_timestamp',i,';');PREPAREs1FROM@stmt;EXECUTEs1;SETi=i+1;ENDWHILE;DROPPREPAREs1;END;INSERTINTOt_datetime(id,log_time,end_time)VALUES(f_id,f_log_time,f_end_time);IFdone1=1THEN--把错误数据记录到表tb_log里。SETi=1;WHILEi<=v_errcountDOSET@stmt=CONCAT('insertintotb_log');SET@stmt=CONCAT(@stmt,'select@errno',i,',@msg',i,',@log_timestamp');PREPAREs1FROM@stmt;EXECUTEs1;SETi=i+1;ENDWHILE;DROPPREPAREs1;ENDIF;END$$DELIMITER;

MySQL5.7发布后,现在可以精简我的代码了。

DELIMITER$$USE`new_feature`$$DROPPROCEDUREIFEXISTS`sp_do_insert`$$CREATEDEFINER=`root`@`localhost`PROCEDURE`sp_do_insert`(INf_idINT,INf_log_timeVARCHAR(255),INf_end_timeVARCHAR(255))BEGINDECLAREiTINYINTDEFAULT1;DECLAREv_errcountINTDEFAULT0;--获取一次错误数据条数DECLAREv_errnoINTDEFAULT0;--获取错误代码DECLAREv_msgTEXT;--获取错误详细信息DECLARECONTINUEHANDLERFORSQLEXCEPTION--定义一个异常处理块BEGINgetstackeddiagnosticsv_errcount=number;WHILEi<=v_errcountDOGETstackedDIAGNOSTICSCONDITIONi--把错误数据分别保存在变量里v_errno=MYSQL_ERRNO,v_msg=MESSAGE_TEXT;INSERTINTOtb_logVALUES(v_errno,v_msg,NOW());SETi=i+1;ENDWHILE;END;INSERTINTOt_datetime(id,log_time,end_time)VALUES(f_id,f_log_time,f_end_time);END$$DELIMITER;

现在来执行下:

mysql>callsp_do_insert(2,'4','5');QueryOK,1rowaffected(0.01sec)

来检索表tb_log的数据。

mysql>select*fromtb_log\G***************************1.row***************************errorno:1265errortext:Datatruncatedforcolumn'log_time'atrow1error_timestamp:2015-11-1711:53:10***************************2.row***************************errorno:1265errortext:Datatruncatedforcolumn'end_time'atrow1error_timestamp:2015-11-1711:53:10***************************3.row***************************errorno:1062errortext:Duplicateentry'2'forkey'PRIMARY'error_timestamp:2015-11-1711:53:103rowsinset(0.00sec)

总结下, 如果先用到DIAGNOSTICS AREA, 最好是在存储过程里面写代码封装SQL。

以上就是【原创】mysql 错误缓冲堆栈_MySQL的内容,更多相关内容请关注搞代码(www.gaodaima.com)!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:【原创】mysql 错误缓冲堆栈_MySQL

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址