当前位置:首页 > 问答 > 正文

MySQL里那些转义字符到底是啥,怎么用才不会出错呢?

说到MySQL里的转义字符,这确实是很多人在写SQL语句,尤其是处理字符串时会遇到的一个头疼问题,你可能遇到过这种情况:你想搜索名字里带单引号的人,O‘Connor”,或者路径里有反斜杠的文件,C:\MyFiles\doc.txt”,如果你直接把这样的字符串写到SQL里,MySQL很可能会报错,因为它会把那个单引号或反斜杠当成有特殊含义的字符,而不是字符串本身的一部分,这就是转义字符要解决的问题。

转义字符就是一个特殊的符号,它告诉MySQL:“嘿,跟在我后面的那个字符,别把它当成特殊符号来处理了,就把它当作一个普通的字符读进去就行。”这个最核心的转义字符,就是反斜杠(\)。(来源:MySQL官方手册中关于“字符串字面量”的章节)

核心转义字符:反斜杠(\)

反斜杠是MySQL默认的转义字符,它的工作方式很简单:在一个用单引号(‘)或双引号(“)括起来的字符串里,当你需要一个有特殊含义的字符失去它的特殊性时,就在它前面加个反斜杠。

哪些是这些“有特殊含义”的字符呢?最常见的有以下几个:

  • 单引号(‘):这是最常需要转义的,字符串通常用单引号界定,所以如果你字符串里本身就有单引号,就必须转义。
    • 错误写法SELECT * FROM users WHERE name = 'O'Connor'; (MySQL会认为字符串在第一个单引号后就结束了,剩下的Connor';就成了非法语法)
    • 正确写法SELECT * FROM users WHERE name = 'O\'Connor'; (反斜杠告诉MySQL,后面的单引号是内容的一部分)
  • 双引号(“):同理,如果你的字符串是用双引号括起来的,而内容里又包含双引号,也需要转义。
    • 正确写法SELECT "He said, \"Hello World!\"";
  • 反斜杠(\)本身:既然反斜杠被赋予了转义的神圣使命,那如果你需要字符串里就包含一个真正的反斜杠该怎么办呢?答案就是用它自己来转义自己。
    • 例子SELECT 'The path is C:\\Windows\\System'; 这样,MySQL存储或输出的结果才会是 The path is C:\Windows\System
  • 换行符和制表符等:反斜杠也用于表示一些不可见的控制字符。
    • \n 代表换行符(Newline)。
    • \t 代表制表符(Tab)。
    • \r 代表回车符(Carriage Return)。
    • \b 代表退格符(Backspace)。
    • SELECT 'Line1\nLine2'; 输出时会显示为两行。

一个重要的特殊情况:LIKE语句中的通配符

当你使用LIKE进行模糊查询时,问题会变得稍微复杂一点,因为LIKE语句有自己的两个特殊字符(通配符):

  • 下划线(_):匹配任意单个字符。
  • 百分号(%):匹配任意多个字符(包括零个)。

假设你想搜索名字中包含字符串“_test”的用户,hello_test”,如果你直接写 ... WHERE name LIKE '%_test%',MySQL会理解成“查找名字中包含任意一个字符紧接着'test'的所有记录”,这会把“atest”、“btest”、“1test”全都搜出来,这显然不是你想要的结果。

这时候,你依然需要转义,但转义谁呢?转义那个有特殊含义的下划线“_”,怎么转义?还是可以用反斜杠:

  • 正确写法... WHERE name LIKE '%\_test%'; 这样,MySQL就知道这个下划线是普通字符,不是通配符。

另一种方法:使用ESCAPE子句自定义转义符

你可能已经发现了,如果我要搜索的字符串里本身就包含很多反斜杠和下划线,比如一个复杂的正则表达式模式字符串,那岂不是要写很多个反斜杠来转义?代码会变得非常难读,像“\\_”这样。

MySQL提供了一个灵活的解决方案:ESCAPE子句。(来源:MySQL官方手册中关于“字符串比较函数和操作符”的LIKE部分)它可以让你指定一个字符作为转义符,而不仅仅是默认的反斜杠。

语法是:LIKE '你的模式字符串' ESCAPE '你选的转义符'

举个例子,假设我们要查找包含“50%”的字符串,但“%”又是通配符,除了用\%,我们也可以自定义:

  • ... WHERE content LIKE '%50|%%' ESCAPE '|'; 这里,我们指定了竖线“|”作为转义符,这句查询的意思是:查找content字段中包含“50%”的字符串,模式字符串中的“|%”被解释为普通的百分号。

怎么用才不会出错?实用建议总结

  1. 养成习惯:只要字符串内容中可能包含单引号(‘)或反斜杠(\),就下意识地想到要转义,这是最常见的错误来源。
  2. 区分场景
    • 在普通的字符串赋值或条件查询()中,主要关心单引号、双引号和反斜杠。
    • 在模糊查询(LIKE)中,要额外关心百分号(%)和下划线(_),并决定是否需要转义它们。
  3. 处理用户输入时最重要:当你通过程序(如PHP、Python、Java)将用户输入的数据拼接到SQL语句中时,这个问题极其危险,不正确的处理不仅会导致程序错误,更会导致SQL注入攻击这种严重的安全漏洞。
  4. 终极安全法则:使用参数化查询(预编译语句) 这是最最重要的一条建议,虽然它稍微超出了纯转义字符的范畴,但必须强调,与其手动地、战战兢兢地去给用户输入的字符串添加反斜杠,不如彻底放弃这种“字符串拼接”构造SQL的方式,你应该使用编程语言提供的参数化查询接口(有时叫预编译语句)。 它的原理是:你写SQL模板,用问号或命名占位符代替变量值,然后单独将参数值传递给数据库驱动,数据库驱动会安全地处理这些值,包括所有必要的转义,从根本上杜绝了SQL注入和转义错误的问题。 伪代码): sql = "SELECT * FROM users WHERE name = ? AND email LIKE ?" cursor.execute(sql, (input_name, "%" + input_domain + "%")) 这样做,你完全不需要担心input_name里有没有单引号,或者input_domain里有没有百分号,数据库驱动会帮你安全、正确地处理好。

理解MySQL转义字符的关键在于分清“字符串的边界”和“字符串的内容”,反斜杠是沟通这两者的桥梁,而在实际应用中,尤其是涉及用户输入时,采用参数化查询是远比手动转义更可靠、更安全的做法。

MySQL里那些转义字符到底是啥,怎么用才不会出错呢?