Navicat仅识别冒号开头的命名占位符(如:start_date),不支持${date}、?或#{xxx};占位符需顶格独占一行并用/+ ... /标注,重复使用有效,混用其他格式将导致无弹窗或报错。
Navicat 里占位符用冒号开头,不是 $ 或 ?
navicat 的参数化查询不认 $date、? 或 #{xxx},只识别以冒号开头的命名占位符,比如 :start_date、:limit_num。写成 ${date} 或 ? 会直接报错或被当作普通字符串处理,根本不会弹出参数输入框。
常见错误现象:执行 SQL 后没弹窗、结果为空、或者报类似 Unknown column ':start_date' in 'where clause' 的错误——说明数据库把占位符当成了字段名或字面量。
- MySQL / PostgreSQL / Oracle 都支持
:param_name写法(Navicat 统一抽象层处理,不用管后端差异) - 不要混用:同一语句里别一会儿用
:a,一会儿用?,Navicat 只响应冒号形式 - 占位符可重复出现,比如
WHERE created_at > :dt AND updated_at ,弹窗只问一次 <code>:dt
执行时自动弹窗,但日期必须输字符串格式
写好含 :my_date 的 SQL 后点“运行”,Navicat 会弹出对话框让你填值。这里最容易踩坑的是日期格式:它不接受 JavaScript 的 new Date()、也不解析 NOW() 函数——你得手动输符合数据库要求的字符串,比如 '2025-06-13' 或 '2025-06-13 14:30:00'。
MySQL 和 PostgreSQL 对单引号敏感:输 2025-06-13(没引号)可能被当数字处理,导致类型转换失败;输 "2025-06-13"(双引号)在 PostgreSQL 里是标识符引用,也会错。
- 安全写法:一律用单引号包裹,如
'2025-06-13'、'2025-06-13 00:00:00' - 时间间隔类参数(如分钟数)可输纯数字,比如
:minutes填30,配合DATE_SUB(NOW(), INTERVAL :minutes MINUTE) - 空值不能留空——要输
NULL(不带引号),否则变成字符串'NULL'
占位符能用在 WHERE、ORDER BY、LIMIT,但不能用在表名或列名
参数只能代入值(value),不能代入标识符(identifier)。也就是说,:table_name 或 :sort_col 这种写法无效,执行时会报语法错误或找不到表。
典型误用场景:想动态切表(SELECT * FROM :tbl)或动态排序(ORDER BY :col),Navicat 不支持。这类需求得靠存储过程、拼接 SQL(需自行防注入),或换用客户端代码处理。
- 可用位置:WHERE 条件、INSERT VALUES、UPDATE SET 右侧、函数参数(如
DATE_ADD(:base, INTERVAL :n DAY)) - 不可用位置:FROM 子句表名、SELECT 列名、GROUP BY 字段、数据库/模式名
- 如果真需要动态表名,建议在 Navicat 外用脚本生成 SQL,再粘贴执行
自定义结果标签名和参数提示共存,但语法不能混写
Navicat 支持两种专用语法:一种是参数占位符 :param,另一种是结果页命名语法 /*+ result_tab_name=订单日报 */。两者可以共存,但必须严格分开,不能嵌套或交叉。
比如写成 /*+ result_tab_name=日报_ :date */ SELECT ... 是错的——注释里不能含占位符,Navicat 会忽略 :date 或报解析异常。
- 正确组合:先写命名注释,再写含
:param的 SQL,例如:
/*+ result_tab_name=用户活跃统计 */ SELECT COUNT(*) FROM users WHERE last_login > :since_date;
- 命名注释必须顶格、独占一行,且用
/*+ ... */格式(加号不能漏) - 参数弹窗标题仍显示
:since_date,不会自动替换成注释里的中文名


















