mysql 诡异的1054错误

2023-05-16

前言

今天在工作中遇到一个非常坑爹的问题,有关Mysql的异常处理,花费了我好几个小时的时间,最后终于解决了,然后根据出现的问题的原因,逆向来看自己解决问题的过程,发现网上的一些文章简直是太坑了,坑的人找不着北啊,最后总结一下吧,免得又踩到这个坑。

先交代一下环境和背景:问题出现在工作的项目中,工程代码在运行的过程中会调用事先定义好的存储过程来保存数据,因为字段太多,大概有好几百个,我就想着把一些废弃的字段删掉,这样一来可以加快存储速度,二来减小数据库的存储大小,于是说干就干,为了避免不必要的麻烦,我决定先改存储过程,在参数中去想不需要存储的字段, 等检测没有问题了再删除表中的字段,就当我改完的时候问题出现了,数据存不上了…

分析过程

是的,数据存不上了,但是程序不报错,理论上如果调用存储过程失败了,程序会打印出错误代码,比如:1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxx' at line 1,但是并没有,我是通过存储过程中的异常打印发现错误的,就是这一句DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL LogError("SetBaseData:SQLEXCEPTION");,存储过程中如果有这一句,当发生异常的时候就可以调用自定义函数LogError("SetBaseData:SQLEXCEPTION")来将错误信息打印到数据库中,可是程序代码为什么不报错呢?这我就想不明白了。

还是想来先来看一下存储过程的示例:

CREATE PROCEDURE SetBaseData(
  IN paramId INT,
  IN paramA INT,
  IN paramB INT,
  IN paramC INT,
  IN paramD INT,
  IN paramE INT,
  IN paramF INT,
  IN paramG INT
)
BEGIN
  DECLARE EXIT HANDLER FOR SQLEXCEPTION CALL LogError("SetBaseData: SQLEXCEPTION");
  UPDATE dataT SET
    A=paramA,
    B=paramB,
    C=paramC,
    D=paramD,
    E=paramE,
    F=paramF,
    G=paramG,
  WHERE Id=paramId; 
END; 

看了这个存储过程是不是感觉很简单,结构是很简单,但是实际的存储过程中可是有好几百个字段需要修改,所以很难查到问题,结果问题就出在我精简字段的过程中,比如我删除无用的字段改成了下面这个样子:

CREATE PROCEDURE SetBaseData(
  IN paramId INT,
  IN paramA INT,
  IN paramB INT,
  IN paramE INT,
  IN paramG INT
)
BEGIN
  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; 

怎么样,发现问题了吗?这样小一个存储过程应该一眼就能发现问题,paramF参数已经删掉了,但是在Update语句中还在使用,这就能解释为什么会触发异常导致数据无法存储了,但是想在几百个字段中找出这样的问题真的很困难,并且参数的顺序和设置的顺序是不一样的,一开始我也没发现,只能在异常结果上分析,有人可能会问我为什么不在程序中下断点,虽然没有打印信息,但是看返回值总能发现问题吧,很遗憾,底层代码被封装了,我只能看到返回了错误的结果,但是却分辨不出是什么错误,奇就奇怪在这,原来存储过程返回错误都是有打印信息的啊。

既然代码看不到,我就只能从存储过程中找原因了,于是我想到使用更细化的异常处理,但是找了半天也不能直接输出异常类型,只能单个捕获,于是上网查了错误代码的分类,发现网上千篇一律的都是下图中的错误代码总结,这正是坑人的地方,其实就是抄来的。

Mysql error

于是我对着这些错误代码挨个检测把存储过程改成了这样:

CREATE PROCEDURE SetBaseData(
  IN paramId INT,
  IN paramA INT,
  IN paramB INT,
  IN paramE INT,
  IN paramG INT
)
BEGIN
  DECLARE EXIT HANDLER FOR 1021 CALL LogError("1021 ");
  DECLARE EXIT HANDLER FOR 1022 CALL LogError("1022 ");
  DECLARE EXIT HANDLER FOR 1027 CALL LogError("1027 ");
  DECLARE 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常见错误代码并不常见。

总结

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

附注

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql 诡异的1054错误 的相关文章

  • 进行 URL 重写

    当我点击网站上给定条目的评论部分时 URL 如下所示 http www com comments index php submission Portugal 20Crushes 20North 20Korea submissionid 62
  • 从 Inno Setup 项目内部调用 MySQL

    我正在为一些使用 MySQL 的软件编写安装程序 我正在尝试运行 sql用于在安装时设置数据库的脚本 唉 我目前在执行它时遇到了很大的问题 这个问题似乎是由于这样一个事实而产生的 当你设置一条通往 sql文件内的 execute SOURC
  • 当我只想更改一个列属性时,是否必须在 SQL 语句中包含所有列属性?

    我有一个 MySQL 数据库 我想通过向所有列添加注释来进行注释 从我读到的MySQL 文档 http dev mysql com doc refman 5 5 en alter table html 在更改其中任何一个时 必须包括数据类型
  • Mysql 按特定字符串排序

    我似乎找不到这个问题的答案 假设我有一个像这样的表 ID Name 1 AAAAAAAAA 2 ABAAAAAAA 3 BBAAAAAAA 4 CDAAAAAAA 5 BBAAAAAAA 有什么办法可以通过以下方式订购name 但是 从说开
  • Python Pandas to_sql,如何创建带有主键的表?

    我想使用 Pandas 的 to sql 函数创建一个 MySQL 表 该函数有一个主键 在 mysql 表中拥有主键通常是件好事 如下所示 group export to sql con db name config table grou
  • “错误 1406:1406:数据对于列来说太长”,但它不应该如此?

    我有以下表结构 DROP TABLE IF EXISTS tblusers 40101 SET saved cs client character set client 40101 SET character set client utf8
  • Sequel Pro / MAMP 在哪里存储本地数据库?

    我通过 Sequel Pro 和 MAMP 在我的计算机上创建了一些数据库 并运行 localhost 来查看它们 但是 我全新安装了 Mac OS Lion 但忘记将数据库备份到 sql 文件 我会定期备份文件 并预装计算机的副本 有谁知
  • MySQL记录保存到数据库的当前时间

    我正在使用 Zend Framework 1 12 和 Mysql 我想在数据库中添加列 该列保存记录插入表中时的当前日期时间 有人知道我如何定义此列吗 此功能必须在 Mysql 站点上运行 而不是在 PHP 站点上运行 您必须将列类型更改
  • MySQL 连接丢失:系统错误:110

    我正在尝试通过专用服务器上的 localhost 连接到 mySQL 服务器 但我不断收到错误 Lost connection to MySQL server at reading initial communication packet
  • 如何在node-mysql查询后获取警告

    如何获取查询执行后识别的相应警告 如下所示 connection query squery function err rows search for OkPacket in 2 dimension array var warningCoun
  • 如何在 python pandas 中的同一列上进行分组并将唯一值的计数和某些值的计数作为聚合?

    我的问题与我之前的问题有关Question https stackoverflow com questions 42022767 how to do group by and take count of one column divide
  • 通过php将MYSQL数据导出到Excel/CSV

    我想通过 php 将 MYSQL 数据导出到 Excel CSV 这样我以后就可以使用我的数据库 或者有人可以使用并理解它 要使用适合 EXCEL 的语法创建 CSV 文件 您可以使用基本 SQL SELECT FROM mytable I
  • 自动生成序列号

    我编写了下面的计数代码 目的是让它为我的数据生成自动序列号 以代替删除行后的 MySQL 序列号 但是当我运行它时 我发现 MySQL 表中没有任何条目 后来我将代码更改为 Dreamweaver 插入记录 并观察到 SN 序列号 字段不需
  • PHP/HTML 添加删除按钮

    我有下面的代码来从数据库中检索行 其中用户名列与基本目录名称匹配 username basename dirname FILE username mysql real escape string username result mysql
  • 从同一mysql服务器的不同数据库复制表

    我有一台带有 2 个数据库的服务器 我想将多个表从一个数据库复制到另一个数据库 目的是我们使用项目中使用的相同用户表 正如在另一个表中使用 InnoDB 和用户表的外键一样 我选择了一种复制方式 为此我对 my cnf 进行了更改 mast
  • LOAD DATA LOCAL INFILE 给出错误:此 MySQL 版本不允许使用命令

    我有一个调用 MySQL 的 PHP 脚本LOAD DATA INFILE从 CSV 文件加载数据 但是 在生产服务器上 我最终遇到了以下错误 用户访问被拒绝 使用密码 是 作为快速解决方法 我将命令更改为LOAD DATA LOCAL I
  • 将附加数据获取到 django 表单下拉选择中

    我有一个具有外键的操作模型 它指定操作重复发生的频率 class Reoccurance models Model label models CharField Label max length 50 unique True days mo
  • 如何像mysql一样对数组进行排序

    如何对与数据库数据相同的数组进行排序 我请求谷歌分析数据 数据是一个大数组 我想将数组与本地数据库中的一些其他字段连接起来 然后我再次扩展大数组 现在我想对大数组进行排序 这与使用我的 sql 相同 如下所示 select from ga
  • MySQL 中两个 Select 查询的结果相减

    我编写了两个 mysql 查询 一个获取一年中特定月份的总用户 注册 另一个获取一年中特定月份的活跃用户 我需要找到数量inactive当年的用户 为此 我正在考虑减去通过两个单独的查询获得的总用户数和活动用户列 以下是查询 1 Fetch
  • 将一段文本保存到mysql

    我正在使用 php 和 mysql 做一个项目 我对此很陌生 现在我必须将一段文本存储到我的数据库中 在表中 对于列 I tried varchar 5000 创建表时但它不允许我 所以请给我一个解决方案 你的 mysql 字段类型应该 T

随机推荐

  • mavros安装流程(超简单)

    只适用于Ubuntu18 04 在Ubuntu中新建一个空白文本 xff0c 命名为123 sh bin bash Bash script for setting up ROS Melodic with Gazebo 9 developme
  • 安装WSL2+Ubuntu18.04(慢慢更新记录)

    1 安装WSL和Ubuntu WSL官网在此 安装 WSL Microsoft Learn Windows下CMD xff0c 先安装WSL2 wsl install 然后进入Microsoft Store xff0c 搜索Ubuntu然后
  • -bash: ./Setup.sh: Permission denied

    sudo chmod 777 xxx
  • Linux 给文件夹或者文件添加权限

    chmod R 777 文件夹 参数 R是递归的意思 777表示开放所有权限 chmod 777 test sh chmod 43 x 某文件 如果给所有人添加可执行权限 xff1a chmod a 43 x 文件名 xff1b 如果给文件
  • Postman使用笔记——Postman发送get请求

    前言 在实际的开发当中 xff0c 我们经常用到get或者post请求 在这篇博客里面分享一下 xff0c 如何在Postman中发送get请求 发送get请求 1 在Postman工作空间选定get请求 图中我们可以看到很多请求方式 xf
  • jdbc连接mysql数据库的详细步骤

    标题 jdbc连接mysql数据库 1 首先在项目根目录创lLib文件夹 xff0c 放入jdbc驱动程序 xff0c 然后Add As Library 2 建包 bean包 xff1a 专门放置属性类 dao包 xff1a 进行数据操作的
  • css高度从0到auto的transition动画

    如题 xff0c 想实现css高度从0到auto的transition动画 xff0c 发现直接写没有效果 查了一下 xff0c 发现可以用max height解决 xff0c 代码如下 lt DOCTYPE html gt lt html
  • beego打包

    beego打包 在main go 对应的目录下 windows平台 xff1a bee pack be GOOS 61 windows 打包后生成一个tar gz文件 xff0c 发送到部署服务器 xff0c 解压gz为tar xff0c
  • C++求解组合数的具体实现

    文章目录 前言问题起因组合公式公式变形递推公式递归实现备忘递归动态规划压缩DP其他优化 总结补充反向递归正向递推 前言 很少写关于具体算法的总结笔记 xff0c 因为很难把一个算法从头到尾的叙述清晰并且完整 xff0c 容易造成误解 这次想
  • protobuf中SerializeToString和SerializePartialToString的区别

    文章目录 前言proto2message定义message扩展注意事项 proto3序列化SerializeToString和SerializeAsString区别SerializeToString和SerializePartialToSt
  • epoll的LT模式(水平触发)和ET模式(边沿触发)

    文章目录 前言名称的记忆状态变化LT模式ET模式数据的读取和发送代码实践基础代码测试分类怎么解决ET触发了一次就不再触发了 总结 前言 epoll的触发模式是个引发讨论非常多的话题 xff0c 网络上这方面总结的文章也很多 xff0c 首先
  • 参考开源项目实现一个简易的C++枚举转字符串的函数

    文章目录 前言改造函数使用各函数的作用总结 前言 前段时间接触了 magic enum 这个开源库 xff0c 代码量不算太多 xff0c 是一个但头文件的枚举操作库 xff0c 关于如何使用还写了一篇总结 推荐一个C 43 43 枚举转字
  • SVN通过备份、过滤、再导入的方式彻底删除废弃目录

    文章目录 前言简要步骤操作示例总结 前言 SVN占用的空间随着项目版本迭代越来越大 xff0c 因为保存了历史记录中的各个版本 xff0c 所以即使本地把废弃的目录删掉提交 xff0c 也不会释放出多余的空间 xff0c 大概率因为操作删除
  • Nginx返回静态的json字符串

    文章目录 前言修改配置文件返回简单json字符串返回json文件内容 总结 前言 自从上次安装完nginx我把服务器对外开发的端口都通过它来转发了 xff0c 真香 xff0c 最近要加一个获取最新版本号的功能 xff0c 一开始还想写在服
  • 前端笔记25——CSS子元素选择器

    前言 前面分享了后代选择器 xff0c 下面分享一下学到的子元素选择器 子元素选择器 子元素选择器是指选择符合条件的子元素 xff0c 需要运用到 gt 符号 xff0c 下面通过实例来看一下 xff1a lt DOCTYPE html g
  • linux下使用dd命令测试磁盘的读写速度

    文章目录 前言D状态进程dd命令问题原因总结 前言 最近打包更新总是特别慢 xff0c 其中有一步使用md5sum命令计算MD5值的操作有时居然要卡一个小时 xff0c 虽说计算MD5比较耗时 xff0c 但通常计算5个G数据的md5值也就
  • .bat批处理(二):%0 %1——给批处理脚本传递参数

    文章目录 前言内容总结 前言 初次接触批处理脚本觉得有点意思 xff0c 所以决定写一个小功能试验一下 xff0c 谁知刚一开始就发现遇到了麻烦 xff0c 本想着使用参数来控制程序的运行结果 xff0c 可是参数怎么传进去呢 xff0c
  • .bat批处理(三):变量声明、设置、拼接、截取

    文章目录 前言内容总结 前言 在使用批处理脚本的时候我们常常会有这类需求 xff0c 比如需要设置一个变量来存储数据 xff0c 简化程序书写 xff1b 拼接现有的内容得到新的变量 xff1b 截取变量的一部分来满足我们的要求 xff0c
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法

    前言 首先说这是一个链接错误而不是编译错误 xff0c 造成这种问题的根本原因就是找得到函数的声明 xff0c 但是找不到函数的实现 xff0c 这是最根本的 xff0c 具体的表现形式有很多 xff0c 我们稍后再做分析 xff0c 下面
  • mysql 诡异的1054错误

    前言 今天在工作中遇到一个非常坑爹的问题 xff0c 有关Mysql的异常处理 xff0c 花费了我好几个小时的时间 xff0c 最后终于解决了 xff0c 然后根据出现的问题的原因 xff0c 逆向来看自己解决问题的过程 xff0c 发现