Na vicat 不支持脚本执行失败后的自动重试,因其命令行工具不捕获 SQL 错误、退出码不可靠、无重试参数且不自动重连;需用外层 shell/batch 脚本封装并基于可识别错误信号实现重试。
先说一个核心结论:Na vicat 本身无法直接实现脚本运行失败后的自动重试。无论是通过图形界面导入,还是使用 na vicat.exe --run-sql 这样的命令行调用,一旦执行过程中间出错,流程就会直接终止,软件内部并没有内置任何重试逻辑。

为什么 na vicat.exe 命令行不支持失败重试
问题出在 Na vicat 命令行工具的设计定位上。它本质上只是一个“触发器”,负责发起一次性的 SQL 执行命令,但并不会深入捕获执行过程中具体的错误类型。比如,脚本是因为锁超时、死锁还是连接中断而失败的?命令行工具对此并不区分。
更关键的是,其退出码(exit code)的语义并不可靠。经验表明,即使 SQL 脚本内部报错,Na vicat 的命令行进程也常常以 0(代表成功)退出。这就让外部的自动化脚本陷入了困境:连“是否失败”都难以准确判断,何谈重试?
- 官方从未提供过任何与重试相关的控制参数,比如
--retry或--max-attempts。 - 所有错误信息虽然会输出到标准错误流(stderr),但格式并非结构化数据,想要通过程序精准匹配特定错误关键词,操作起来相当繁琐。
- 对于连接中断这类临时性问题,命令行模式通常也不会自动尝试重连,更不用说重新执行脚本了。
可行替代方案:用 shell/batch 封装 + 条件判断
那么,有没有办法实现呢?答案是肯定的,但需要换个思路:自己动手,用外层的批处理或 Shell 脚本把 Na vicat 命令“包装”起来。这个方案的核心在于,首先要确保能捕捉到 Na vicat 执行失败时发出的、可以被识别的信号,然后再基于这个信号来设计循环重试的逻辑。
- Windows Batch 示例(此方法需要 Na vicat 16 及以上版本,且能正确返回非零退出码):
set MAX_RETRY=3 set RETRY=0 :retry na vicat.exe --run-sql "C:\script.sql" --connection "MyDB" if %ERRORLEVEL% NEQ 0 ( set /a RETRY+=1 if %RETRY% LEQ %MAX_RETRY% ( timeout /t 2 >nul goto retry ) else ( echo Failed after %MAX_RETRY% attempts. exit /b 1 ) ) - macOS/Linux Bash 示例(通常更可靠):
#!/bin/bash MAX_RETRY=3 for ((i=0; i
- 这里有个至关重要的前提:你必须先确认你使用的 Na vicat 版本,在 SQL 执行失败时,是否会真实地返回非零的
exit code。市场上不乏这样的案例,一些旧版本(如 15.x)可能会忽略错误,始终返回 0。如果遇到这种情况,就需要放弃依赖退出码,转而采用分析输出日志、匹配“Error”等关键词的方式来判断是否失败。
比命令行重试更稳的做法:换用 mysql 客户端
话说回来,如果你的核心目标仅仅是“稳定地执行 SQL 脚本并在失败时重试”,那么绕开 Na vicat 命令行,直接使用数据库原生的客户端工具,往往是更简单、更可控的选择。
- 例如,直接使用原生的
mysql命令行客户端(需要提前安装):mysql -h host -u user -p'pass' db_name < script.sql
它在遇到语法错误、连接失败等情况时,会稳定地返回非零退出码,这为构建重试逻辑提供了坚实的基础。 - 你可以轻松地配合
until或while循环来实现重试,并且能精细控制重试间隔、最大次数,甚至根据不同的错误信息进行过滤处理。 - 这引出了一个值得思考的点:Na vicat 的核心价值在于其强大的可视化建模、数据同步和备份恢复等高级功能。对于纯粹的 SQL 批量执行与自动化任务,它并非最专精的工具。
最后,需要警惕的是一个容易被忽略的“暗坑”:Na vicat 的 --run-sql 命令在底层实际上会启动一个隐藏的图形界面进程。这意味着,如果系统没有可用的图形会话(比如在远程 SSH 无 X11 转发、或者在无显示器的 CI/CD 环境中),这个命令可能会直接卡死或静默失败。这种“不可见的依赖”,往往比设计重试逻辑本身,更容易导致自动化流程意外中断。
