ToB企服应用市场:ToB评测及商务社交产业平台

标题: DML操作报列不存在? [打印本页]

作者: 灌篮少年    时间: 2024-12-13 11:01
标题: DML操作报列不存在?
DML操作报列不存在?

背景概述

客户在测试时发实际行某些DML语句时,出现了异常情况,报表不存在或者列不匹配的情况;
我在做数据迁移测试的时候也出现此问题,迁移数据时报 unknow column;
看到这种情况的时候很奇怪,查看表结构时也能看到当前实行的SQL语句涉及的表及列是存在的;
经过排查,最终发现当前这张表涉及触发器,报错的也不是这张表,而是其他表。
问题复现

本次测试基于 GreatSQL 8.0.32
1.创建测试表
  1. greatsql> CREATE TABLE t1 (c1 int,c2 int,c3 int,c4 int);
  2. greatsql> INSERT INTO t1 VALUES (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4);
  3. greatsql> CREATE TABLE t2 (c5 int,c6 int,c7 int,c8 int);
  4. greatsql> INSERT INTO t2 VALUES (1,1,1,1),(2,2,2,2),(3,3,3,3),(4,4,4,4);
复制代码
2.创建触发器
  1. # t2表不存在c1列
  2. greatsql> CREATE TRIGGER test1
  3. after INSERT on t1
  4. FOR EACH ROW
  5. INSERT INTO t2(c1) values(NEW.c1);
  6. Query OK, 0 rows affected (0.02 sec)
  7. greatsql> CREATE TRIGGER test2
  8. after UPDATE on t1
  9. FOR EACH ROW
  10. UPDATE test.t2 SET c1=(NEW.c1)+1 WHERE c1=(NEW.c1);
  11. Query OK, 0 rows affected (0.02 sec)
  12. greatsql> CREATE TRIGGER test3
  13. after DELETE on t1
  14. FOR EACH ROW
  15. DELETE FROM t2 WHERE c1=(OLD.c1);
  16. Query OK, 0 rows affected (0.02 sec)
  17. # t3表不存在
  18. greatsql> CREATE TRIGGER test4
  19. before UPDATE on t2
  20. FOR EACH ROW
  21. INSERT INTO t3(c1) values(NEW.c5);
  22. Query OK, 0 rows affected (0.00 sec)
复制代码
可以看到在创建触发器的时候,不会去判定语句中涉及的表或者列是否存在。
3.实行测试SQL
  1. greatsql> INSERT INTO test.t1 values (1,1,1,1);
  2. ERROR 1054 (42S22): Unknown column 'c1' in 'field list'
  3. greatsql> UPDATE test.t1 SET c1=110 WHERE c1=1;
  4. ERROR 1054 (42S22): Unknown column 'c1' in 'field list'
  5. greatsql> DELETE FROM  test.t1 WHERE c1=1;
  6. ERROR 1054 (42S22): Unknown column 'c1' in 'where clause'
  7. greatsql> UPDATE t2 SET c5=110 WHERE c5=1;
  8. ERROR 1146 (42S02): Table 'test.t3' doesn't exist
复制代码
此时报错c1列不存在,但没有表现是具体那张表的c1列,因此对我们产生误导,明明t1表存在c1列,但是还是报错c1列不存在;
4.故障排查

碰到上述问题时,我们可以打开通用日志,观察一下日志中记载的语句
  1. shell> tail -f general5000.log
  2. ...
  3. 2024-10-14T16:21:16.837007+08:00         2651 Query     INSERT INTO test.t1 values (1,1,1,1)
  4. 2024-10-14T16:21:16.839500+08:00         2651 Query     INSERT INTO t2(c1) values(NEW.c1)
  5. ...
复制代码
可以看到当我们实行了 INSERT INTO test.t1 语句后紧接着自动实行 INSERT INTO t2(c1) 语句,因为t2表没有c1列,所以报错 Unknown column 'c1'。
5.查看当前表涉及的触发器
  1. greatsql> SELECT TRIGGER_SCHEMA,TRIGGER_NAME,EVENT_OBJECT_SCHEMA,EVENT_OBJECT_TABLE,ACTION_STATEMENT FROM INFORMATION_SCHEMA.TRIGGERS WHERE EVENT_OBJECT_TABLE='t1';
  2. +----------------+--------------+---------------------+--------------------+----------------------------------------------------+
  3. | TRIGGER_SCHEMA | TRIGGER_NAME | EVENT_OBJECT_SCHEMA | EVENT_OBJECT_TABLE | ACTION_STATEMENT                                   |
  4. +----------------+--------------+---------------------+--------------------+----------------------------------------------------+
  5. | test           | test1        | test                | t1                 | INSERT INTO t2(c1) values(NEW.c1)                  |
  6. | test           | test2        | test                | t1                 | UPDATE test.t2 SET c1=(NEW.c1)+1 WHERE c1=(NEW.c1) |
  7. | test           | test3        | test                | t1                 | DELETE FROM t2 WHERE c1=(OLD.c1)                   |
  8. +----------------+--------------+---------------------+--------------------+----------------------------------------------------+
  9. 3 rows in set (0.00 sec)
复制代码
当出现上面的问题时,可以查看一下这张表是否涉及触发器;如果涉及则检查一下对应触发器的ACTION_STATEMENT字段中的SQL语句涉及的表是否包含报错的字段。
总结

如果出现在实行DML操作时报错,而且报错跟当前表没有什么关系时可以思量是否有触发器与当前表有关联,检查一下触发器中涉及的SQL语句.

Enjoy GreatSQL
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4