为啥我需要双转义(使用 4 \)才能在纯 SQL 中找到反斜杠( \ )?

Posted

技术标签:

【中文标题】为啥我需要双转义(使用 4 \\)才能在纯 SQL 中找到反斜杠( \\ )?【英文标题】:Why I need to double-escape (use 4 \) to find a backslash ( \ ) in pure SQL?为什么我需要双转义(使用 4 \)才能在纯 SQL 中找到反斜杠( \ )? 【发布时间】:2012-11-05 01:44:02 【问题描述】:

我不理解 mysql 的这种行为:如果我想显示 a\b,我可以选择 "a\\b",它可以正常工作:

mysql> select "a\\b";
+-----+
| a\b |
+-----+
| a\b |
+-----+
1 row in set (0.05 sec)

但是,如果我想使用 LIKE 在表中搜索包含 \ 的字符串,我需要对我的“\”进行双重转义。为什么?

这是一个例子。

我们准备了一张小桌子。

create table test ( test varchar(255) );
insert into test values ( "a\\b" ) , ( "a\\b\\c" ) , ( "abcd" );

mysql> select * from test;
+-------+
| test  |
+-------+
| a\b   |
| a\b\c |
| abcd  |
+-------+
3 rows in set (0.05 sec)

我们尝试获取以“a\b”开头的条目...

mysql> select * from test where test LIKE "a\\b%";
+------+
| test |
+------+
| abcd |
+------+
1 row in set (0.05 sec)

为什么\\ 在那里被忽略了?为什么我需要双转义 basckslash 才能获得预期的结果?

mysql> select * from test where test LIKE "a\\\\b%";
+-------+
| test  |
+-------+
| a\b   |
| a\b\c |
+-------+
2 rows in set (0.04 sec)

【问题讨论】:

【参考方案1】:

您首先对字符串语法进行转义,然后对LIKE 语法进行转义。

LIKE中的字符%_有特殊含义,所以如果要搜索字面量%,则需要使用\%,如果要搜索字面量\%你需要像\\%一样转义反斜杠。

在字符串语法中" 显然具有特殊含义,因此如果要在字符串中包含引号,则需要将其转义为\",并在字符串中包含文字\",则必须转义反斜杠如\\"

因此,在这两种语法中,您都必须转义 \


如果您不想使用\ 来转义 LIKE 模式,可以使用 ESCAPE 关键字。例如:

...  where test LIKE "a\\b%" ESCAPE '|';

这样,您需要编写 |%|_|| 来转义这些特殊字符。

【讨论】:

我在想这样的行为,但这很不自然……解析的层次太多了。想象一下,如果我需要在 php 中提出这样的请求,我需要转义 4 次反斜杠(所以使用 `\\\\\\\`),因为 PHP 也有自己的解释器。 是的,确实如此。在 PHP 字符串中,您需要再次转义。您可以将其视为将数据放入一个盒子中。如果你想在 PHP 字符串中使用正则表达式来搜索它,那就更要转义了! :) 请记住不要在 LIKE 中搜索多个 `\` :p【参考方案2】:

见String Comparison Functions

like 运算符与可能包括%_ 的模式进行比较。要逃避这些,您必须使用\。所以反斜杠也是一个特殊字符。

当您输入模式字符串 "a\\\\b" 时,它会由 Mysql 解释,然后由 like 运算符再次解释,即给出 "a\\b",然后是 "a\b"

【讨论】:

以上是关于为啥我需要双转义(使用 4 \)才能在纯 SQL 中找到反斜杠( \ )?的主要内容,如果未能解决你的问题,请参考以下文章

mysql怎么样才能插入单引号

存储过程中执行sql语句时如何转义双引号?

jquery 冒号转义 为啥双斜杠

c# SSIS脚本组件中的转义双引号从SQL数据发送JSON

为啥SQL支持两个单引号以及反斜杠转义

为啥这个 Sql 语句(有 2 个表连接)需要 5 分钟才能完成?