如何将SQL查询中的参数转换为问号占位符并保留原始查询语句
SQL参数值替换为问号占位符实现方案
正则表达式方案
适合简单场景的快速处理,按以下步骤执行即可覆盖绝大多数常规SQL:
- 替换单引号包裹的字符串字面量(兼容单引号转义场景:字符串内的单引号用两个单引号表示)
- 匹配正则:
'[^']*(?:''[^']*)*' - 替换值:
?
- 匹配正则:
- 替换独立数字字面量(避免匹配到表名、列名中包含的数字)
- 匹配正则:
\b\d+\b - 替换值:
?
- 匹配正则:
- 替换布尔值、NULL字面量
- 匹配正则:
\b(TRUE|FALSE|NULL)\b(匹配时忽略大小写) - 替换值:
?
- 匹配正则:
注意:正则方案无法处理带SQL注释、嵌套字符串、特殊转义符的复杂SQL,容易出现误匹配,生产环境复杂场景推荐使用语法解析类工具。
开源工具方案
基于SQL语法解析树(AST)实现常量替换,准确率远高于正则,支持各类复杂SQL语法:
- pg_query:PostgreSQL专用开源解析库,基于PostgreSQL官方语法解析内核开发,可直接解析SQL生成AST,遍历AST替换所有常量节点为?即可,支持所有PG兼容的SQL语法,替换准确率100%。
- SQLFluff:跨数据库支持的开源SQL处理工具,支持MySQL、PostgreSQL、SQL Server等十余种数据库语法,可自定义规则遍历AST中的常量节点统一替换为?。
- jSQLParser:Java生态开源SQL解析库,轻量易集成,支持主流数据库语法,内置常量节点遍历能力,几行代码即可完成替换。
如果是PostgreSQL生态的使用场景,还可以直接复用pg_stat_statements的queryid:在应用侧或者数据库日志层记录原始SQL和对应queryid,直接和pg_stat_statements中存储的参数化SQL通过queryid关联即可,无需自己实现替换逻辑。
内容的提问来源于stack exchange,提问作者Oto Shavadze
相关产品推荐
相关产品推荐

