You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么SQLite3参数化查询在LIKE语句中不会自动转义通配元字符?

核心原因

SQLite的参数化查询仅负责转义SQL语法层面的特殊字符(比如单引号、语句分隔符这类会破坏SQL结构、引发注入风险的字符),不会自动处理LIKE子句下的专属通配符。
参数化的设计边界是保证传入参数不会被解析为SQL指令的一部分,不会识别你SQL中具体使用了什么操作符、操作符本身有什么特殊语义规则,所以传入的_和%进入LIKE表达式后,依然会被按照通配符规则解析,这不是参数化失效,是功能边界本来就不覆盖这部分逻辑。
这也解释了为什么等值查询WHERE column = ?没有问题:=操作符本身不存在通配符语义,所有传入字符都会被当做普通字面量处理,自然不需要额外转义。

实现方案

不需要在Python层额外编写独立的转义校验函数,直接利用SQLite原生支持的LIKE自定义转义符能力,把转义逻辑内嵌在SQL语句中即可,完全适配现有参数化传值的写法。
修正后的代码如下:

con = sqlite3.connect('database.db')
cursorObj = con.cursor()

# 声明!为转义符,在SQL内部完成通配符转义
sqlStatement = """
SELECT * FROM usertable 
WHERE username LIKE '%' || replace(replace(replace(?, '!', '!!'), '%', '!%'), '_', '!_') || '%'
ESCAPE '!'
"""
cursorObj.execute(sqlStatement, ("_", ))
rows = cursorObj.fetchall()

逻辑说明:

  • 转义逻辑全部在SQL语句内部通过内置replace函数实现,不需要在数据库逻辑外写额外处理代码
  • 优先替换转义符本身!为!!,避免参数本身携带!时转义逻辑错乱
  • 再将参数内的%替换为!%、_替换为!_,配合ESCAPE '!'声明后,这两个字符会被识别为普通字面量,不再触发通配符匹配
  • 全程使用参数化传值,不会引入SQL注入风险

不要在Python层提前做字符串替换拼接参数,将转义逻辑放在SQL侧实现,既可以避免多场景复用时漏转义的问题,也能和现有加密存储、解密读取的逻辑完全解耦。

内容的提问来源于stack exchange,提问作者noNameNitwit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:21:36