Navicat无危险SQL弹窗机制,需手动启用SET SQL_SAFE_UPDATES = 1和SET AUTOCOMMIT = 0组合防御:前者拦截无WHERE或非索引WHERE的DELETE/UPDATE,后者使DML暂存并支持ROLLBACK,右下角显示“Transaction”为激活标志,执行后须查SELECT ROW_COUNT()确认实际影响行数。
Navicat 本身没有“危险SQL执行确认”弹窗机制
navicat 不像某些 ide(如 dbeaver)那样对 delete、update、drop 等语句自动弹出二次确认。它默认行为是:只要语句语法合法、权限足够,回车就执行——尤其在 autocommit = 1 下,删完即永久丢失。
真正起作用的是手动事务 + SQL_SAFE_UPDATES 组合
这不是界面开关,而是靠会话级 SQL 控制的防御层。每次连上生产库后,必须在第一个查询窗口中运行:
SET SQL_SAFE_UPDATES = 1; SET AUTOCOMMIT = 0;
这样做的效果是:
-
SQL_SAFE_UPDATES = 1会直接拒绝执行无WHERE或WHERE不命中索引的DELETE/UPDATE,报错而非静默执行 -
AUTOCOMMIT = 0让所有 DML 进入暂存状态,必须显式COMMIT才生效,误操作后可立刻ROLLBACK - 右下角状态栏出现 Transaction 字样,才是事务已激活的唯一可信信号
为什么不能依赖 Navicat 的“自动提交”图形开关
这个选项位置不统一(v15 在「编辑连接→高级」,v16/v17 可能被隐藏),且即使勾掉,某些驱动(如 MySQL X DevAPI、SQL Server Windows 身份验证)会忽略客户端设置,强制服务端控制。验证是否真正生效的方法是:
执行 UPDATE users SET name='test' WHERE id = 999999999;(确保无匹配行),再立即查 SELECT @@autocommit; —— 若返回 1,说明服务端未受控,得改用 SET SESSION autocommit = OFF; 或去数据库配置文件里设默认值。
影响行数不准时,ROW_COUNT() 是唯一可信依据
Navicat 底部显示的 “Affected rows” 常因 SQL_SAFE_UPDATES 拦截、会话复用或协议解析问题变成 0,容易误判为“没执行”。安全做法是:
- 每条
DELETE/UPDATE后,立刻跟一句SELECT ROW_COUNT() AS affected; - 避免在同一窗口混写多条语句(如
DELETE; SELECT ROW_COUNT();),Navicat 15/16 对分号分隔批处理的行数反馈极不稳定 - 若
ROW_COUNT()返回0,先检查WHERE条件是否真能命中数据,而不是假设“它没删成”
真正的确认不在弹窗里,而在你是否看到 ROW_COUNT() 的数字、是否看清了 Transaction 状态、是否在敲 COMMIT 前停顿了三秒。











