Navicat计划任务不支持@var用户变量,因其底层调用命令行SQL执行器而非交互式会话,导致SET @days=30等语句被静默忽略,看似执行成功实则未生效。
Navicat计划任务根本不支持@var用户变量
这不是配置错误,而是设计限制:navicat 17的「自动化任务」底层调用的是命令行 sql 执行器,不是交互式会话,所以所有 @var 形式的用户变量(包括 set @days = 30、select @x)都会被跳过或当作无效标识符处理。你看到“执行成功”,实际可能一行都没生效。
SQL脚本里写@days却没报错?那是被静默忽略了
Navicat 计划任务默认以查询模式执行,语法容错高:SET @days = 30; 这行直接跳过;后续 WHERE created_at 中的 <code>@days 被当 NULL 处理,条件恒为假——DELETE 一条不删,还不会报错。
- 验证方法只有两个:
SELECT ROW_COUNT();加在脚本末尾,看返回是否为 0;或者执行后查表确认数据是否真被删了 - 日志里绝不会出现“变量未定义”提示,只写
SQL executed successfully - 别依赖手动执行能跑通的脚本,计划任务和手动执行是两套执行环境
真正可用的替代方案只有两类
想动态控制逻辑,必须绕开 @var,改用数据库原生能力或外部注入:
-
硬编码常量:最稳,比如直接写
DELETE FROM logs WHERE created_at -
数据库函数替代:MySQL 用
DATE_SUB(NOW(), INTERVAL 30 DAY),PostgreSQL 用NOW() - INTERVAL '30 days',避免中间变量 -
操作系统环境变量 + 数据库读取:在 Windows 任务计划程序「操作 → 添加参数」里传入
--env "LOG_DAYS=30",再在 SQL 里靠sys_eval('echo $LOG_DAYS')(MySQL)或current_setting('app.log_days')(PostgreSQL,需提前SET app.log_days = '30')读取 -
Navicat 内置宏仅限备份/导出任务:
${DATE}、${TIME}在 SQL 脚本里完全无效,别试
最容易被忽略的调试盲区
很多人改完脚本就重跑任务,但没意识到:Navicat 不会自动重载任务里的 SQL 文件内容。你改了本地 .sql 文件,必须重新导入到任务配置里,或者手动编辑任务中的「SQL 脚本」文本框,否则运行的还是旧版本。这个缓存行为没有提示,连刷新按钮都不起作用。


















