因为 MySQL 在字符串中使用的是 C 的转义句法(例如
“/n”),
所以在 LIKE 字符串中使用的任何一个 “/” 必须被双写。
例如,为了查找 “/n”,必须以 “//n” 形式指定它。为了查找 “/”,必须指定它为 “////”
(反斜线被语法分析器剥离一次,另一次在模式匹配时完成,留下一条单独的反斜线被匹配)。
示例(译者注):
CREATE TABLE `ta` (
`id` int(3) unsigned NOT NULL,
`memo` char(6) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `ta` VALUES("1", "a//");
INSERT INTO `ta` VALUES("2", "a////");
INSERT INTO `ta` VALUES("3", "a//n");
INSERT INTO `ta` VALUES("4", "a/n");
INSERT INTO `ta` VALUES("5", "a//%");
mysql> SELECT * FROM `ta`;
+----+------+
| id | memo |
+----+------+
| 1 | a/ |
| 2 | a// |
| 3 | a/n |
| 4 | a
|
| 5 | a/% |
+----+------+
mysql> SELECT * FROM `ta` WHERE `memo` =
'a//';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////';
+----+------+
| id | memo |
+----+------+
| 1 | a/ |
+----+------+
# 在 LIKE 子句中,为了查找 “/”,必须指定它为 “////”
mysql> SELECT * FROM `ta` WHERE `memo` =
'a////';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////////';
+----+------+
| id | memo |
+----+------+
| 2 | a// |
+----+------+
# 在 LIKE 子句中,为了查找 “/”,必须指定它为 “////”
mysql> SELECT * FROM `ta` WHERE `memo` =
'a//n';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////n';
+----+------+
| id | memo |
+----+------+
| 3 | a/n |
+----+------+
# 在 LIKE 子句中,为了查找 “/”,必须指定它为 “////”
=========================================================
# 通过以上三个示例我的理解为 “////”在 LIKE 子句中用于匹配一个“/”字符
# (反斜线被语法分析器剥离一次,另一次在模式匹配时完成,留下一条单独的反斜线被匹配)
# 'a////n' 被剥离了两个反斜线后为“a//n”,
# 字串中的第一个反斜线是转义符,对第二个反斜线进行转义
=========================================================
mysql> SELECT * FROM `ta` WHERE `memo` =
'a/n';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a///n';
+----+------+
| id | memo |
+----+------+
| 4 | a
|
+----+------+
# 'a///n' 经两次剥离后为“a/n”,字串中的反斜线是一个转义符。
# 字串 “a/n” 匹配字串 ASCII(0x610A)
mysql> SELECT * FROM `ta` WHERE `memo` =
'a//%';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a/////%';
+----+------+
| id | memo |
+----+------+
| 5 | a/% |
+----+------+
# 'a/////%' 经两次剥离后为“a///%”,字串中的第一个和第三个反斜线是转义符
# 分别转义一个 “/” 和 换行符,字串匹配 “a/%”。
===========================================================
# 我的疑惑:
# 手册中提到:
# 为了查找 “/n”,必须以 “//n” 形式指定它。(to search for `/n', specify it as
`//n')
# 原文中的这个 “/n” 是什么?一个换行符(应该用 “///n” 表示)?
# 两个字符(也应该用 “a////n” 表示)??
# 就此如止,手册中对此描述还不算有什么太大的问题,
# (to search for `/n', specify it as `//n'),
# (must double any `/' that you use in your LIKE strings)
# 我们假设这两个描述只不过是一个笔误!
# 下面还有更令人惊讶的!
===========================================================
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a//';
+----+------+
| id | memo |
+----+------+
| 1 | a/ |
+----+------+
# 串 “a////” 经两次剥离一次转义后匹配 “a/”
# 而 “a//” 呢,第一个反斜线就是转义?该字串没有经两次剥离??
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////////';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a//////';
+----+------+
| id | memo |
+----+------+
| 2 | a// |
+----+------+
# 同样的,串 “a//////” 的前四个反斜线经两次剥离一次转义后匹配 “a/”
# 而后两个反斜线呢?怎么匹配到一个 “/” 了?
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////n';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a//////n';
+----+------+
| id | memo |
+----+------+
| 3 | a/n |
+----+------+
# 同样的,串 “a//////n” 的前四个反斜线经两次剥离一次转义后匹配 “a/”
# 而后两个反斜线呢?被剥离了??
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a///n';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a/n';
+----+------+
| id | memo |
+----+------+
| 4 | a
|
+----+------+
# 字串 “a/n” 没有经任何剥离?直接转义为一个换行符??
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a///%';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////%';
+----+------+
| id | memo |
+----+------+
| 1 | a/ |
| 2 | a// |
| 3 | a/n |
| 5 | a/% |
+----+------+
# 既然 'a///n' 可以匹配 ASCII(0x610A)
# 为什么 'a///%' 就不是匹配 “a%” 而是匹配 “a/”+任意字符 呢
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a/////%';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a//////%';
+----+------+
| id | memo |
+----+------+
| 5 | a/% |
+----+------+
1 row in set (0.00 sec)
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a///////%';
mysql> SELECT * FROM `ta` WHERE `memo` LIKE
'a////////%';
+----+------+
| id | memo |
+----+------+
| 2 | a// |
+----+------+
1 row in set (0.00 sec)
* 以上结果在 MySQL 3.23.56 、MySQL 4.0.12 、MySQL 4.1 中测试通过
示例结束(译者注):
use test;
tee d:/test.txt;
CREATE TABLE `ta` (
`id` int(3) unsigned NOT NULL,
`memo` char(6) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `ta` VALUES("1", "a//");
INSERT INTO `ta` VALUES("2", "a////");
INSERT INTO `ta` VALUES("3", "a//n");
INSERT INTO `ta` VALUES("4", "a/n");
INSERT INTO `ta` VALUES("5", "a//%");
SELECT * FROM `ta`;
SELECT * FROM `ta` WHERE `memo` = 'a//';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////';
SELECT * FROM `ta` WHERE `memo` = 'a////';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////////';
SELECT * FROM `ta` WHERE `memo` = 'a//n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////n';
SELECT * FROM `ta` WHERE `memo` = 'a/n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a///n';
SELECT * FROM `ta` WHERE `memo` = 'a//%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a/////%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////';
SELECT * FROM `ta` WHERE `memo` LIKE 'a//';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////////';
SELECT * FROM `ta` WHERE `memo` LIKE 'a//////';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a//////n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a///n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a/n';
SELECT * FROM `ta` WHERE `memo` LIKE 'a///%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a/////%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a//////%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a///////%';
SELECT * FROM `ta` WHERE `memo` LIKE 'a////////%';
字符转移是递归处理的,看看:
原始:a////n
第一次 a//n
第二次 a/n
又如:a//////n
第一次 a////n
第二次 a//n
第三次 a/n
直到/没有可以匹配的转移字符为止。//,////这种情况会不停的转是因此/这个字符的二进制编码造成的。你可以说是bug,但是就是那么回事。
分享到:
相关推荐
模式匹配主要通过`LIKE`或`NOT LIKE`运算符在`WHERE`子句中实现,适用于处理`char`、`varchar`、`text`、`datetime`等类型的字段。 1. **模式匹配符号**: - `%`:这个符号代表零个、一个或多个任意字符。例如,在...
- `SELECT...FROM...`:查询数据,可以配合`GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `DESC`, `ASC`, `COUNT`, `SUM`, `AVG`, `MAX`, `MIN`等子句。 7. **PHP MySQL API**: - `mysql_connect()`:建立数据库...
在MySQL中,正则表达式主要用于`WHERE`子句中的`REGEXP`或`RLIKE`操作符,使得我们可以根据模式匹配来查询数据。 首先,我们需要了解正则表达式的基本语法。在MySQL中,正则表达式遵循Perl兼容正则表达式(PCRE)...
SQLite使用自定义的转义机制,不同于其他数据库系统如MySQL或PostgreSQL使用反斜杠`\`作为转义字符。在SQLite中,转义字符是`/`,即在需要转义的特殊字符前加上一个`/`。例如,要查找包含`%`字符的记录,应将查询中...
这两个操作符用于在WHERE子句中进行模式匹配,与LIKE操作符类似,但regexp提供了更强大的模式匹配能力。当使用REGEXP进行匹配时,如果模式匹配被测试值的任何部分,它就认为匹配成功。这与LIKE不同,LIKE要求整个被...
你可以用它来在 WHERE 子句中定义模式,如 `%` 和 `_` 通配符。 - `%` 代表零个、一个或多个字符,例如 `SELECT * FROM table WHERE column LIKE 'abc%'` 将返回所有以 "abc" 开头的记录。 - `_` 代表单个字符,...
5. **条件查询**:使用`WHERE`子句进行条件过滤,`LIKE`用于模糊匹配,`BETWEEN`用于范围查找。 6. **连接操作**:在PHP中,使用`mysqli_connect`或`PDO`类建立与MySQL服务器的连接,`mysqli_query`执行SQL语句。 ...
27. LIKE:用于在WHERE子句中指定搜索模式。 28. LIMIT:用于限制查询结果的数量。 29. LOAD DATA INFILE:从文件中加载数据到表中的SQL命令。 30. LONG:用于指定大文本字段的数据类型。 31. MEDIUMINT:指定数据...
30. 避免SQL注入:使用参数化查询或适当的转义机制是防止SQL注入攻击的常见做法。 对于MySQL的海量数据查询优化,还应当考虑硬件配置、操作系统设置、网络传输以及服务器上的其他应用程序对数据库性能的影响。...
`BETWEEN`和`LIKE`用于范围查询和模糊匹配,例如`LIKE`可以用于查找包含特定模式的数据,但在匹配下划线 (_) 时需要进行转义,写为`\_%`。`ORDER BY`用于排序结果,`GROUP BY`则用于对数据进行分组,配合`HAVING`...
- **预防措施** 包括使用参数化查询、转义特殊字符等。 5. **什么是视图(View)?在业务中通常用它来做什么?** - **视图** 是基于SQL查询的结果集的虚拟表。 - **用途** 包括简化复杂查询、保护数据等。 6. *...
6. 在 MySQL 中,不能使用 "\" 作为转义符,而是使用其他字符,如 '!'. 7. 创建表和插入数据: CREATE TABLE a (name VARCHAR(10)) GO INSERT INTO a SELECT '11%22' UNION ALL SELECT '11%33' UNION ALL SELECT '...
- **使用WHERE子句**: ```sql SELECT 字段 FROM 表名 WHERE 条件表达式; ``` - **使用NOT**: - 否定条件表达式: ```sql SELECT * FROM 表名 WHERE NOT 条件表达式; ``` - **使用LIKE进行模糊查询**: -...
若要匹配特殊字符,可以使用`ESCAPE`关键字定义转义字符,例如`SELECT * FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$';`。 `BETWEEN`关键字用于指定一个范围,如`SELECT * FROM employees WHERE ...
- 特殊比较运算符如`BETWEEN`用于指定范围,`IN`用于检查值是否在给定列表内,`LIKE`则支持模糊匹配,配合`%`和`_`通配符使用,还可以通过`ESCAPE`来定义转义字符。 在实际操作中,应尽量避免录入`NULL`值,并合理...
总的来说,处理MySQL特殊字符时,要确保对字符串进行适当的转义或使用参数化查询,同时注意对`LIKE`子句中的百分比符号的处理,以及字段名与关键字的冲突。使用Python的数据库适配器提供的安全功能,可以避免许多...
正则表达式在MySQL中用于复杂模式匹配,例如在`LIKE`或`REGEXP`操作符后使用。正则表达式可以进行更复杂的文本搜索,如查找所有以特定字符串开头的记录。例如,`SELECT * FROM users WHERE username REGEXP '^john';...
在上面的代码中,`$searchTerm`是用户输入的搜索关键词,已转义以防止SQL注入。`prepare()`方法用于准备SQL语句,`execute()`方法用于执行该语句,`fetchAll()`则用于获取所有结果。 为了提高搜索效率,可能还需要...
接着,`WHERE`子句中的条件`column_name LIKE 0x257061737325`表明了搜索以'%'(0x25的ASCII值)开头,然后是'pass',最后也是'%'的列名。这里的'%'是SQL通配符,用于匹配任意数量的字符。攻击者可能是在寻找包含'...