首页 > 编程知识 正文

数据库连接10061错误,mysql出现1054错误

时间:2023-05-06 13:47:00 阅读:43025 作者:337

前言今天,我在工作中遇到了一个漏洞百出的问题。 关于Mysql的异常处理,我花了好几个小时,最后终于解决了。 而根据出现问题的原因,反过来看自己解决问题的过程,网上有些文章漏洞百出,漏洞百出的人找不到北啊。 最后总结一下。 别再踩这个洞了。

首先,说明环境和背景。 如果正在处理的项目遇到问题,工程代码将在运行时调用预定义的存储过程来保存数据。 字段太多,有数百个,因此可以删除已销毁的字段以加快存储速度。 第二,减小数据库的存储大小。 这么说来,为了避免无谓的故障,我们决定修改存储过程,以考虑参数中不需要存储的字段。 等等

分析过程就是这样。 无法保存数据,但程序不报告错误。 理论上,如果存储过程调用失败,程序将打印错误代码。 示例: 1064-youhaveanerrorinyoursqlsyntax; checkthemanualthatcorrespondstoyourmysqlserversionfortherightsyntaxtousenear ' XXX ' at line 1,但没有。 我在保存中的异常打印中发现了错误。 此declareexithandlerforsqlexceptioncalllogerror (' set base data : sqlexception ' );存储过程中有此语句,可以在发生异常时调用自定义函数log error ' set base data : sqlexception '将错误消息打印到数据库中,但程序代码为什么不报告错误这个我不知道。

看看存储过程的示例:

createproceduresetbasedata (inparam idint,IN paramA INT,IN paramB INT,IN paramC INT,IN paramD INT,IN paramE INT, in paramf int inparam gint (begindeclareexithandlerforsqlexceptioncallogerror ) ' setbasedata:sqlexception ' ); 更新数据集a=parama,B=paramB,C=paramC,D=paramD,E=paramE,F=paramF,G=paramG,WHERE Id=paramId; 结束; 看看这个存储过程,你觉得很简单吗? 虽然结构很简单,但很难找到问题,因为实际存储过程需要修改数百个字段。 结果,问题发生在我精简场地的过程中。 例如,删除了无用的字段,修改如下:

createproceduresetbasedata (inparam idint,IN paramA INT,IN paramB INT,IN paramE INT,IN paramG INT ) begindeclareexithandlerfor B=paramB,E=paramE,F=paramF,G=paramG,WHERE Id=paramId; 结束; 怎么样,发现问题了吗? 这样魔幻的黑米个存储过程应该一眼就能发现问题。 paramF参数已删除,但仍在Update语句中使用。 这可以解释为什么会出现异常而无法保存数据,但在数百个字段中发现这样的问题真的很难。 另外,参数的顺序和设定的顺序不同。 一开始我不知道。 只能用例外结果分析。 有人可能会问,为什么不在程序中添加断点,虽然没有打印信息,但通过查看返回值总是会发现问题。 很遗憾,基本代码是封装的,只能看到返回错误的结果,但不知道是什么样的错误。 不可思议的是,存储过程的返回错误包含打印信息。

既然看不到代码,就只能从存储过程中查找原因。 因此,我们考虑了使用更细化的异常处理,但是即使找了半天也无法直接输出异常类型,只能单独进行捕获。 因此,在网上调查了错误代码的分类,网上总结了如下图所示的错误代码。 这正是漏洞所在,其实是抄的。

因此,我逐一检查了这些错误代码,并将存储过程更改为:

createproceduresetbasedata (inparam idint,IN paramA INT,IN paramB INT,IN paramE INT,IN paramG INT ) begindeclareexithandlerfor declareexithandlerfor 1027呼叫记录器(' 1027 ); 德克尔

E EXIT HANDLER FOR 1036 CALL LogError("1036 "); DECLARE EXIT HANDLER FOR 1048 CALL LogError("1048 "); DECLARE EXIT HANDLER FOR 1062 CALL LogError("1062 "); DECLARE EXIT HANDLER FOR 1099 CALL LogError("1099 "); DECLARE EXIT HANDLER FOR 1100 CALL LogError("1100 "); DECLARE EXIT HANDLER FOR 1104 CALL LogError("1104 "); DECLARE EXIT HANDLER FOR 1106 CALL LogError("1106 "); DECLARE EXIT HANDLER FOR 1114 CALL LogError("1114 "); DECLARE EXIT HANDLER FOR 1150 CALL LogError("1150 "); DECLARE EXIT HANDLER FOR 1165 CALL LogError("1165 "); DECLARE EXIT HANDLER FOR 1242 CALL LogError("1242 "); DECLARE EXIT HANDLER FOR 1263 CALL LogError("1263 "); DECLARE EXIT HANDLER FOR 1264 CALL LogError("1264 "); DECLARE EXIT HANDLER FOR 1265 CALL LogError("1265 "); DECLARE EXIT HANDLER FOR 1312 CALL LogError("1312 "); DECLARE EXIT HANDLER FOR 1317 CALL LogError("1317 "); DECLARE EXIT HANDLER FOR 1319 CALL LogError("1319 "); DECLARE EXIT HANDLER FOR 1325 CALL LogError("1325 "); DECLARE EXIT HANDLER FOR 1326 CALL LogError("1326 "); DECLARE EXIT HANDLER FOR 1328 CALL LogError("1328 "); DECLARE EXIT HANDLER FOR 1329 CALL LogError("1329 "); DECLARE EXIT HANDLER FOR 1336 CALL LogError("1336 "); DECLARE EXIT HANDLER FOR 1337 CALL LogError("1337 "); DECLARE EXIT HANDLER FOR 1338 CALL LogError("1338 "); DECLARE EXIT HANDLER FOR 1339 CALL LogError("1339 "); DECLARE EXIT HANDLER FOR 1348 CALL LogError("1348 "); DECLARE EXIT HANDLER FOR 1357 CALL LogError("1357 "); DECLARE EXIT HANDLER FOR 1358 CALL LogError("1358 "); DECLARE EXIT HANDLER FOR 1362 CALL LogError("1362 "); DECLARE EXIT HANDLER FOR 1363 CALL LogError("1363 "); DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL LogError("SetBaseData: SQLEXCEPTION"); UPDATE dataT SET A=paramA, B=paramB, E=paramE, F=paramF, G=paramG, WHERE Id=paramId; END;

看到这里是不是觉得我丧心病狂,确实是,但是我没有办法了啊,可是事与愿违,这么狠毒的代码最终也没有捕获到错误,可见网上的常见错误代码其实没什么卵用,接下来我就想既然代码中不打印错误,那么我直接在Mysql客户端调用存储过程总行了吧,一开始没这么做主要是字段太多了,好几百个呀,现在没办法了,只能试一试我对照着参数的类型,一个个输入,最后call运行存储过程,诡异的事情发生了,没有任何报错,甚至警告都没有,但是数据还是没有保存上,简直要疯了。没办法最终只能一行一行的看存储过程的定义了,那可是好几百行啊,这种定义和C++代码不同,根本就没有跳转,只能靠脑袋记忆,我又没用IDE,只能硬着头皮看了,还好功夫不负有心人,最后让我发现了问题,就是paramF参数已经删掉了,但是在Update语句中还在使用这样的情况,于是我改正了过来,发现保存数据没有问题了。

可是我那么多捕获异常的代码就白写了吗?于是我又还原了回去,结果令人震惊的一幕发生了,程序就然报错了,就是我刚才改过的那一句,1054 - Unknown column 'paramF' in 'field list',你说奇不奇怪,我都找到问题了,你居然又明确的指出来了,早干嘛去了,不过这条消息还算有点用,起码让我知道这是”1054异常”啊,于是我把这个异常在存储过程中做了处理,加了一句DECLARE EXIT HANDLER FOR 1054 CALL LogError("1054 ");这次果然在调试信息中发现了这个错误,于是上网查了一下1054的含义,就是说某个变量没有出现在参数列表中.

为此我还查了一下Mysql的官网,发现Mysql的官网上列举了错误1002到4531总共有3000多个,看来网上的Mysql常见错误代码并不常见。

总结 通过这件事让我再一次发现代码的诡异遇到问题还得相信自己,还是自己最靠谱网上查资料要注意甄别,我发现网上流传的常见错误代码中连“1064 sql 语法错误”都没有包含,看来它并不常见还是想直接在存储过程中输出异常的类型,不想一个个的捕获,我还没找到方法,希望有经验的大神能给我一点点指导。 附注

我还是把Mysql官网指出的错误贴在这:Mysql Error Codes

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。