ERROR 1064 表示 SQL 语法错误,主因是关键字拼错、标点遗漏、保留字未加反引号;sql_safe_updates=1 会静默拒绝无有效 WHERE 的 UPDATE/DELETE。

看到 ERROR 1064 就该先看 SQL 有没有拼错关键字
这是 MySQL 最常见的语法错误,本质是解析器在某个位置“看不懂”你写的 SQL。不是所有拼写错误都会报这个码,但绝大多数 ERROR 1064 都指向关键词、标点或保留字误用。
-
SELECT * FROM user WHERE name = '张三' ORDER BY id ASC LIMIT 10 OFFSET—— 后面漏了数字,会直接报ERROR 1064 - 把
GROUP BY写成GROUPBY(少空格),或INNER JOIN写成INNTER JOIN(多字母) - 用
order、group、rank这类词当字段名却没加反引号:SELECT rank FROM users→ 应写成SELECT `rank` FROM users - MySQL 8.0+ 中
json是保留字,CREATE TABLE t(json TEXT)会失败,得写成`json`
执行 UPDATE/DELETE 没生效?先确认是否启用了 safe mode
MySQL 默认开启 sql_safe_updates=1,它会拒绝没有 WHERE 条件或 WHERE 不含主键/索引列的修改语句——这不是报错,而是静默拒绝,容易让人误以为 SQL 执行成功了。
- 检查当前设置:
SELECT @@sql_safe_updates;,返回1表示启用 - 临时关闭(仅当前会话):
SET sql_safe_updates = 0; - 真正要改数据前,先用
SELECT复现WHERE条件:SELECT id FROM orders WHERE status = 'pending' AND updated_at ,确认能查出预期行数再执行UPDATE - 生产环境不建议全局关掉,可改用带主键的条件,比如
WHERE id IN (1001,1002,1003)
遇到 ERROR 1292:Truncated incorrect double/integer value
这说明你在对数值类型字段赋了非法值,比如把字符串塞进 INT 列,或把超长小数塞进 DECIMAL(5,2)。MySQL 5.7+ 默认严格模式下会直接报错,老版本可能只警告并截断。
- 典型场景:
INSERT INTO products(price) VALUES('99.99 USD');→ 字符串含非数字字符,触发ERROR 1292 - 排查方法:用
SELECT CAST('99.99 USD' AS DECIMAL)测试转换结果,MySQL 会返回0.00并产生 warning - 修复方向:清洗数据(正则提取数字)、改用
VARCHAR存原始值、或在应用层做类型校验 - 注意:
STR_TO_DATE()解析失败也会报同类错误,例如STR_TO_DATE('2024/13/01', '%Y/%m/%d')(13 月不存在)
事务里执行失败后,别忘了检查 autocommit 和 ROLLBACK 状态
很多异常看起来“没报错”,但数据不对,根源常在事务控制混乱。尤其 ORM 或脚本中手动 BEGIN 后忘记 COMMIT 或 ROLLBACK。
- 确认当前连接是否自动提交:
SELECT @@autocommit;,0表示关闭,需显式COMMIT - 执行出错后,如果没
ROLLBACK,事务仍处于打开状态,后续语句可能被意外包含进去 - 用
SELECT trx_state, trx_started, trx_query FROM information_schema.INNODB_TRX;查看未提交事务 - 简单测试法:在命令行连上 MySQL,执行
BEGIN; INSERT ...; SELECT * FROM t;(查不到刚插的行)→ 说明还没提交,不是 SQL 问题,是事务卡住了
SQL 报错本身只是表象,背后往往是数据状态、会话配置、权限边界或事务生命周期没理清。盯着错误码看两眼,再查一次 SHOW WARNINGS;,比重写十遍 SQL 更管用。










