日志记录

有几种方法可以调试 MySQL 脚本。例如,有时可能需要记录每个 SQL 请求。为此,可以使用以下命令:

SET GLOBAL general_log = 'ON';
SET GLOBAL log_output = 'TABLE';

这样,服务器的每个请求都会被记录到系统数据库 mysql 中的 general_log 表。

异常处理

在 MySQL 中,像 "除以零" 这样的异常不会返回错误,而是返回 NULL

然而,一些操作表时可能会遇到异常,例如为了避免插入列表在中途因为 "UNIQUE" 约束而停止。以下示例适用于 InnoDB 表(而不是 MyISAM):

ALTER TABLE `MyTable1` ADD UNIQUE(`id`);

INSERT INTO MyTable1 (id) VALUES('1');
START TRANSACTION;
      INSERT INTO MyTable1 (id) VALUES('2');
      INSERT INTO MyTable1 (id) VALUES('3');
      INSERT INTO MyTable1 (id) VALUES('1');
IF condition THEN
  COMMIT;
ELSE
  ROLLBACK;
END IF;

在这里,当插入第二个 id=1 时会抛出错误。但根据某个条件,脚本可以取消插入 2 和 3,或者不管怎样提交它们。

默认情况下,MySQL 设置为自动提交(autocommit),这意味着每个操作后会自动执行 COMMIT(使得 ROLLBACK 无效)。要禁用自动提交,可以使用以下命令:

SET autocommit = 0;

注意:当多个 COMMIT 在一个 ROLLBACK 前执行时(例如在循环中),它将只取消最后一次 COMMIT 后的操作。

常见错误

  • 1130: Host 'example.com' is not allowed to connect to this MySQL server

    当从远程计算机连接时,使用的帐户未被授权。可以设置为:

    GRANT ALL PRIVILEGES ON *.* TO 'MyUser1'@'%' WITH GRANT OPTION;
    

    代替或与以下命令一起使用:

    GRANT ALL PRIVILEGES ON *.* TO 'MyUser1'@'localhost' WITH GRANT OPTION;
    
  • 1093 - You can't specify target table '...' for update in FROM clause

    当试图根据相同表的选定行删除一些记录时,会发生此错误。只需使用临时表来解决:

    CREATE TEMPORARY TABLE temp_table AS SELECT * FROM original_table WHERE condition;
    DELETE FROM original_table WHERE id IN (SELECT id FROM temp_table);
    
  • 2003: Can't connect to MySQL server

    更改 "host" 参数。

  • Invalid use of group function

    SELECT 查询中,使用 HAVING 替代 WHERE 来根据其他记录修改字段。

    对于 UPDATEDELETE,被 IN 比较的字段不能属于同一类型。

  • SQLSTATE[42000]: Syntax error or access violation

    使用 phpMyAdmin 查找确切的语法错误位置。

  • This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

    用某些 JOIN 语句替代 "IN"。

参考链接:MySQL 事务和 autocommit 讨论

最后修改: 2025年01月17日 星期五 19:38