MySQL 触发器的坑:ERROR 1054 (42S22): Unknown column 'xxx' in 'field list'

更新日期: 2019-05-14 阅读次数: 4646 字数: 776 分类: MySQL

今天线上项目报错了 500 错误,Laravel 日志中显示

Illuminate/Database/QueryException with message 'SQLSTATE[42S22]: 
Column not found: 1054 Unknown column 'is_charge' in 'field list' 
(SQL: update `some_categories` set `lft` = case when `lft` >= 29 then `lft`+2 else `lft` end, `rgt` = case when `rgt` >= 29 then `rgt`+2 else `rgt` end where (`lft` >= 29 or `rgt` >= 29))'

即新增层级菜单的时候,更新历史节点的 left right 值报错。

但是,报错很诡异,SQL 语句中并没有 is_charge 出现,但是却一直报

Column not found: 1054 Unknown column 'is_charge' in 'field list' 

这个错误很常见,以往都是因为线上数据表表没有同步新增字段,引起字段缺失。但是,完全不相关的 SQL 语句怎么会报出这个错误呢?

排除 Laravel 的问题

为了排除是 Laravel 的三方依赖问题,我直接在 MySQL 命令行中执行测试:

mysql> update some_categories set is_charge = 1 where id = 241;
ERROR 1054 (42S22): Unknown column 'is_charge' in 'field list'
mysql> update some_categories set type = 1 where id = 241;
ERROR 1054 (42S22): Unknown column 'is_charge' in 'field list'

果然,都是同样的错误,这么简单的 SQL 语句都会报错,说明不是单纯的 SQL 拼写错误。

我猜测是这个表有 MySQL 的触发器。

排查 MySQL 的触发器

SELECT * FROM information_schema.TRIGGERS \G;

果然找到了对应的触发器

TRIGGER_CATALOG: def
            TRIGGER_SCHEMA: db1
              TRIGGER_NAME: some_categories_insert
        EVENT_MANIPULATION: INSERT
      EVENT_OBJECT_CATALOG: def
       EVENT_OBJECT_SCHEMA: db1
        EVENT_OBJECT_TABLE: some_categories
              ACTION_ORDER: 1
          ACTION_CONDITION: NULL
          ACTION_STATEMENT: BEGIN INSERT INTO db2.some_categories (id,name,type,link,page_id,page_id,parent_id,lft,rgt,depth,image,created_at,updated_at,is_charge) VALUES (NEW.i$,NEW.name,NEW.type,NEW.link,NEW.page_id,NEW.parent_id,NEW.lft,NEW.rgt,NEW.depth,NEW.image,NEW.created_at,NEW.updated_at,NEW.is_charge);
END

问题很明显了,对应的同步数据库 db2 里的对应表,缺少了 is_charge 字段。确认了一下,确实如此。

问题解决。

参考:https://bugs.mysql.com/bug.php?id=68715

战斗还没有结束

新增字段之后,不报之前的错误了。但是又出现了一个新的错误。

[2019-05-13 22:47:49] production.ERROR: SQLSTATE[21S01]: 
Insert value list does not match column list: 
1136 Column count doesn't match value count at row 1
 (SQL: insert into `some_categories` (`name`, `parent_id`, `lft`, `rgt`, `updated_at`, `created_at`) values (测试测试, 225, 29, 30, 2019-05-13 22:47:49, 2019-05-13 22:47:49)) 

Column count doesn't match value count 这个错误也很容易理解,就是字段名列表跟值列表个数不匹配。检查了 SQL 没有问题,看来又是触发器的问题了。

在 MySQL 命令行下做了验证,确实如此

mysql> insert into some_categories (name, `type`) values ('test', 1);
ERROR 1136 (21S01): Column count doesn't match value count at row 1

晚上实在太困,到了凌晨,效率更低,愣是没看出触发器那里写错了字段。我决定先睡觉去。。。

今天一早,瞬间发现 page_id,page_id 写了两遍。。。

去掉一个之后,就恢复正常了。

结论

  • MySQL 排除 SQL 语句问题时,最好在 MySQL 命令行中进行。没有干扰。
  • 触发器确实少用比较好,容易忘掉他的存在
  • MySQL 的提示确实不够友好。没有注明是触发器中的问题。感觉想尝试其他数据库了。
  • 凌晨排查问题效率太低,不能指望人肉排查
领取阿里云/腾讯云服务器优惠券

关于作者

我是来自山东烟台的一名开发者,喜欢瞎折腾,顺便记记笔记。有敢兴趣的话题,欢迎加微信 zhongwei 聊聊。 白天写程序,晚上哄熊孩子,可能回复有点慢,见谅。 查看更多联系方式

相关文章

爱评论不评论

近期节日

2020年04月01日 愚人节
2020年04月02日 国际儿童图书日
2020年04月03日 寒食节
2020年04月04日 清明节
2020年04月07日 世界卫生日
2020年04月11日 世界帕金森病日
2020年04月19日 谷雨
2020年04月21日 复活节
2020年04月22日 世界地球日
2020年04月23日 世界读书日
2020年04月26日 知识产权日
2020年04月30日 佛诞
查看更多节日