唯一安全做法是使用参数化查询;LIKE中%和_需用ESCAPE显式转义,如'%50!%' ESCAPE '!',不同数据库语法各异,手动字符串替换不可靠且易出错。

直接用参数化查询,别手动拼接字符串——这是唯一能兼顾安全与正确性的做法。所有手动转义方案都存在漏判、多层编码、数据库方言差异等隐患。
LIKE 查询里 % 和 _ 怎么安全匹配
这两个字符在 LIKE 中是通配符,用户输入若含真实 % 或 _,必须显式声明转义符,不能依赖反斜杠默认生效。
- Oracle / MySQL / PostgreSQL 都需用
ESCAPE关键字,例如:WHERE name LIKE '%%%' ESCAPE '' - SQL Server 更推荐方括号语法:
WHERE name LIKE '%[%]%'或WHERE name LIKE '%[_]%',避免转义符冲突 - PostgreSQL 不认
作默认转义符,必须指定单字符如ESCAPE '!',且该字符本身不能出现在待查文本中 - 别写
LIKE '%user_input%'后再对user_input做字符串替换——容易漏掉嵌套转义或重复转义
单引号和双引号怎么处理才不报错
单引号是 SQL 字符串边界符,双引号在多数数据库中用于标识符(如列名),但语义因库而异。
- 插入含单引号的值,标准写法是两个单引号:
'O''Reilly',不是'O'Reilly'(后者在某些模式下会出错) - MySQL 允许用反斜杠转义单引号(
'O'Reilly'),但仅限于NO_BACKSLASH_ESCAPES关闭时;开启后反而会报错 - 双引号在 PostgreSQL / SQL Server 中可包列名,但作为字符串字面量时行为不统一——Oracle 不支持双引号字符串,SQLite 支持但需开启
PRAGMA double_quote_literals - 真正安全的做法:把这类值全交给参数占位符,例如
INSERT INTO t (name) VALUES (?),由驱动自动处理引号
为什么不能靠 string.replace() 手动清理用户输入
因为转义逻辑和数据库连接层、字符集、SQL 模式强耦合,简单替换会掩盖深层问题。
-
mysql_real_escape_string()已废弃,且不处理%和_——它只防注入,不管LIKE语义 - JavaScript 侧做
replace(/'/g, "''")看似能解决单引号,但遇到\'或 UTF-8 多字节字符时极易崩坏 - 不同数据库对
&、$、{}等字符是否需要转义完全不一致;Oracle 里&还可能被 SQL*Plus 当变量前缀提前解析 - 最隐蔽的坑:同一段 SQL 在开发环境(UTF8MB4)和生产环境(AL32UTF8)下,对 emoji 或补充字符的转义结果可能完全不同
参数化查询不是“更推荐”,而是事实标准。哪怕你确认当前只用 MySQL、只查 LIKE、只处理 ASCII 输入,只要业务存在演进可能,手动转义就注定成为技术债。真正的合规化,是从第一行 SQL 构建开始就放弃字符串拼接。

















