navicat 默认不支持多语句事务,需手动点击“开始事务”按钮启用;begin/commit等sql语句无效,事务由navicat控制;多语句须在同一窗口执行,避免分号后空格、换行或注释;postgresql中begin须独占一行;mysqldump生成的set autocommit=0必须删除。

Navicat 默认不支持多语句事务执行,必须手动开启事务上下文
Navicat 的 SQL 编辑器默认以单语句模式运行,遇到分号 ; 就终止当前语句解析,后续内容被丢弃或报错 SQL syntax error 或 unexpected token。这不是 bug,而是底层 JDBC/ODBC 连接默认禁用 allowMultiQueries=true。你写的 BEGIN; INSERT; UPDATE; COMMIT; 会被拆成四条独立语句执行,中间任意一条失败,前面的已自动提交生效。
真正起作用的是 Navicat 自己维护的事务开关状态,不是 SQL 里的 BEGIN 关键字。所以第一步永远是:点工具栏 开始事务 按钮(或按 Ctrl+T),看到状态栏显示 Transaction started 才算就位。
- 不要依赖“运行批处理”(
Ctrl+Shift+R)——它按分号切分并逐条发送,每条都在独立事务中自动提交 - 不要在脚本开头写
BEGIN;或START TRANSACTION;,除非你明确知道它只是普通语句、实际事务由 Navicat 控制 - PostgreSQL 用户注意:
BEGIN必须独占一行,不能和INSERT写在同一行,否则解析直接失败
多条语句必须粘贴在同一查询窗口内,且格式要干净
开启事务后,所有语句必须在同一个查询窗口中执行。复制粘贴时容易带入干扰项,导致解析中断或部分语句失效。
- 每条语句结尾用
;,但分号后不要跟空格、换行或注释(如INSERT ... ; -- 注释容易被截断) - 避免 Windows 的
\r\n和 Unix 的\n混用,尤其含多行字符串或注释时;建议用 VS Code 统一转为 LF - 删掉文件里残留的
DELIMITER $$—— Navicat 不识别自定义分隔符,除非你手动改成DELIMITER $$ ... $$ DELIMITER ;包裹整段 - 如果 SQL 文件来自
mysqldump --opt,大概率含SET AUTOCOMMIT = 0;,必须删掉,否则和 Navicat 的手动事务冲突
执行与确认必须分步操作,不能跳过影响行数检查
事务开启后执行语句,Navicat 不会自动告诉你改了几行。一旦漏看,COMMIT 就等于永久生效。
- 先执行验证查询:
SELECT COUNT(*) FROM orders WHERE status = 'pending' AND created_at - 再执行 DML:
DELETE FROM orders WHERE status = 'pending' AND created_at - 立刻查影响行数:
SELECT ROW_COUNT();(MySQL)或直接看底部状态栏的Affected rows - 确认无误再按
Ctrl+S提交;出错立即按Ctrl+Z回滚 -
SET AUTOCOMMIT = 0;只对当前标签页会话有效,关掉就失效,每次连生产库第一件事就是重设
导入大 SQL 文件时,“手动提交”设置比写脚本更重要
还原整个数据库或大批量数据时,别靠手写事务包裹,Navicat 的“运行 SQL 文件”对话框里有更稳的控制项。
- 务必勾选
手动提交(不自动提交):让整个文件在单个事务中执行 - 取消勾选
每批提交:否则它会在你设的“每批记录数”处强制COMMIT,破坏原子性 - 把
每批记录数调到50000(上限),太小会频繁切片,太大可能内存溢出 - 提前清理文件里的
USE database_name;—— 合并多个文件时只保留第一个,其余删掉,避免上下文切换失败 - 勾选
遇到错误继续,防止DROP TABLE IF EXISTS报错中断流程,但它不跳过语法错误
最常被忽略的其实是事务边界和语句格式的耦合:你以为自己写了事务,其实 Navicat 根本没把它当一回事;你以为分号只是结束符,它却可能因一个空格或 BOM 头就停在第 3 行。安全不是靠“记得回滚”,而是让每一步都不可绕过验证。











