当前位置: 首页 > 面试题库 >

转义MySQL通配符

红弘盛
2023-03-14
问题内容

在较旧的服务器上,我无法使用准备好的语句,因为我目前正试图在将用户输入发送到MySQL之前完全转义用户输入。为此,我正在使用PHP函数mysql_real_escape_string

由于此函数无法转义MySQL通配符%和_,因此我也正addcslashes对这些通配符进行转义。

当我发送类似:

test_test " '

到数据库,然后再读回数据库,显示:

test\_test " '

看着这个,我不明白为什么_前面有一个反斜杠,但是“和’却没有。因为它们都用\进行了转义,因此_’和”应该都显示相同,即,所有转义字符都可见或所有的东西都不可见。

是否自动筛选了转义的\

谁能解释一下?


问题答案:

_%不是通配符在MySQL一般,而且不应该被转义,将它们放入普通的字符串字面量的目的。mysql_real_escape_string是正确的,足以满足此目的。addcslashes不应该使用。

_并且%仅在LIKE-matching
上下文中是特殊的。当您想为LIKE语句中的文字使用准备字符串时,要100%匹配百分之一百,而不仅仅是以100开头的任何字符串,都需要担心两种转义。

首先是喜欢转义。LIKE处理完全在SQL内部进行,如果要将文字字符串转换为文字LIKE表达式, 即使使用参数化查询, 也必须执行此步骤!

在此方案中,_并且%是特殊的,必须进行转义。转义字符也必须转义。根据ANSI SQL,除这些字符外, 不得
转义:\'这是错误的。(尽管MySQL通常会让您摆脱它。)

完成此操作后,您进入第二个转义级别,这是普通的旧字符串文字转义。这发生在SQL之外,创建SQL,因此必须在LIKE转义步骤之后完成。对于MySQL,这mysql_real_escape_string和以前一样。对于其他数据库,它将具有不同的html" target="_blank">功能,您可以只使用参数化查询来避免这样做。

这里引起混乱的问题是,在MySQL中,两个嵌套转义步骤都使用反斜杠作为转义字符!因此,如果要将字符串与文字百分号匹配,则必须双反斜杠转义并说出LIKE 'something\\%'。或者,如果在PHP "文字中也使用反斜杠转义,则"LIKE 'something\\\\%'"。啊!

根据ANSI
SQL,这是不正确的,它表示:在字符串文字中,反斜杠表示文字反斜杠,而转义单引号的方式为'';在LIKE表达式中,默认情况下根本没有转义符。

因此,如果要以可移植的方式进行LIKE逸出,则应覆盖默认(错误)行为,并使用该LIKE ... ESCAPE ...构造指定自己的逸出字符。为了理智,我们将选择除该死的反斜杠以外的其他东西!

function like($s, $e) {
    return str_replace(array($e, '_', '%'), array($e.$e, $e.'_', $e.'%'), $s);
}

$escapedname= mysql_real_escape_string(like($name, '='));
$query= "... WHERE name LIKE '%$escapedname%' ESCAPE '=' AND ...";

或带有参数(例如在PDO中):

$q= $db->prepare("... WHERE name LIKE ? ESCAPE '=' AND ...");
$q->bindValue(1, '%'.like($name, '=').'%', PDO::PARAM_STR);

(如果您希望有更多的可移植性聚会时间,那么尝试考虑MS SQL
Server和Sybase也可能会很有趣,因为在[错误的情况下,该字符在LIKE语句中也很特殊,必须转义。argh。)



 类似资料:
  • 问题内容: 在Oracle中使用SQL运算符时,如何转义通配符(和)? 我今天遇到一个愚蠢的问题。我需要使用来搜索varchar列上是否存在下划线。正如预期的那样,它不起作用- 因为根据SQL,下划线是通配符。这是我的(简化)代码: 我在PostgreSQL中尝试了以下查询,它们返回了我想要的行: 不幸的是,它在Oracle 12c中不起作用。是否有“标准”的转义通配符方式?还是至少在Oracle

  • 问题内容: (注意:这个问题不是关于转义查询,而是关于转义结果) 我正在使用GROUP_CONCAT将多行合并为一个逗号分隔的列表。例如,假设我有两个(示例)表: 我想列出所有帖子以及对帖子发表评论的每个用户名的列表: 给我: 这很好用,但是如果用户名包含逗号会破坏用户列表。MySQL是否具有可以让我转义这些字符的功能?(请假定用户名可以包含任何字符,因为这只是示例架构) 问题答案: 如果用户名中

  • 问题内容: 和MySQL中的通配符有什么区别? 在这样的查询中: 问题答案: 只能在全文搜索中用作通配符(或截断),而(匹配0个或更多字符)和(恰好匹配一个字符)仅适用于LIKE查询。

  • 问题内容: PHP必须正确地转义任何可能引起问题的字符。为BASH模仿此功能的最佳方法是什么? 无论如何,有使用bash做准备好的mysql语句吗?这似乎是最好的方法。 我的大多数变量都不会(不应)具有特殊字符,但是我为用户提供了完全自由的密码密码。它可能包含’和’之类的字符。 我可能正在执行多个SQL语句,所以我想创建一个包含参数并随后运行该语句的脚本。这是我到目前为止的内容: doSQL.sh

  • 问题内容: 如何在like子句中转义通配符? 例如: 有任何想法吗? 问题答案: 在Hibernate 3中,可以使用escape参数指定转义字符: 我认为这应该可行,尽管我从未在实践中尝试过。

  • 在 MySQL 中,除了常见的字符之外,我们还会遇到一些特殊的字符,如换行符、回车符等。这些符号无法用字符来表示,因此需要使用某些特殊的字符来表示特殊的含义,这些字符就是转义字符。 转义字符一般以反斜杠符号 开头,用来说明后面的字符不是字符本身的含义,而是表示其它的含义。MySQL 中常见的转义字符如下表所示。 转义字符 转义后的字符 \" 双引号(") \' 单引号(') \\ 反斜线(\) \