如何在MySQL中转义特殊字符?

69 mysql

例如:

select * from tablename where fields like "%string "hi"  %";
Run Code Online (Sandbox Code Playgroud)

错误:

您的SQL语法有错误; 检查与您的MySQL服务器版本对应的手册,以便在第1行的'hi""'附近使用正确的语法

如何构建此查询?

Pau*_*xon 102

本回答中提供的信息可能导致不安全的编程习惯.

此处提供的信息在很大程度上取决于MySQL配置,包括(但不限于)程序版本,数据库客户端和使用的字符编码.

请参阅http://dev.mysql.com/doc/refman/5.0/en/string-literals.html

MySQL recognizes the following escape sequences.
\0     An ASCII NUL (0x00) character.
\'     A single quote (“'”) character.
\"     A double quote (“"”) character.
\b     A backspace character.
\n     A newline (linefeed) character.
\r     A carriage return character.
\t     A tab character.
\Z     ASCII 26 (Control-Z). See note following the table.
\\     A backslash (“\”) character.
\%     A “%” character. See note following the table.
\_     A “_” character. See note following the table.

所以你需要

select * from tablename where fields like "%string \"hi\" %";
Run Code Online (Sandbox Code Playgroud)

虽然Bill Karwin如下所述,但对字符串分隔符使用双引号不是标准SQL,因此使用单引号是一种好习惯.这简化了事情:

select * from tablename where fields like '%string "hi" %';
Run Code Online (Sandbox Code Playgroud)

  • 为什么逃离角色是不安全的? (3认同)

Wal*_*lid 29

我在Java中开发了自己的MySQL转义方法(如果对任何人都有用).

请参阅下面的类代码.

警告:如果启用了NO_BACKSLASH_ESCAPES SQL模式,则会出错.

private static final HashMap<String,String> sqlTokens;
private static Pattern sqlTokenPattern;

static
{           
    //MySQL escape sequences: http://dev.mysql.com/doc/refman/5.1/en/string-syntax.html
    String[][] search_regex_replacement = new String[][]
    {
                //search string     search regex        sql replacement regex
            {   "\u0000"    ,       "\\x00"     ,       "\\\\0"     },
            {   "'"         ,       "'"         ,       "\\\\'"     },
            {   "\""        ,       "\""        ,       "\\\\\""    },
            {   "\b"        ,       "\\x08"     ,       "\\\\b"     },
            {   "\n"        ,       "\\n"       ,       "\\\\n"     },
            {   "\r"        ,       "\\r"       ,       "\\\\r"     },
            {   "\t"        ,       "\\t"       ,       "\\\\t"     },
            {   "\u001A"    ,       "\\x1A"     ,       "\\\\Z"     },
            {   "\\"        ,       "\\\\"      ,       "\\\\\\\\"  }
    };

    sqlTokens = new HashMap<String,String>();
    String patternStr = "";
    for (String[] srr : search_regex_replacement)
    {
        sqlTokens.put(srr[0], srr[2]);
        patternStr += (patternStr.isEmpty() ? "" : "|") + srr[1];            
    }
    sqlTokenPattern = Pattern.compile('(' + patternStr + ')');
}


public static String escape(String s)
{
    Matcher matcher = sqlTokenPattern.matcher(s);
    StringBuffer sb = new StringBuffer();
    while(matcher.find())
    {
        matcher.appendReplacement(sb, sqlTokens.get(matcher.group(1)));
    }
    matcher.appendTail(sb);
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)


Bil*_*win 28

您应该使用单引号作为字符串分隔符.单引号是标准的SQL字符串分隔符,双引号是标识符分隔符(因此您可以在表或列的名称中使用特殊的单词或字符).

在MySQL中,默认情况下双引号(非标准地)作为字符串分隔符工作(除非您设置ANSISQL模式).如果您使用其他品牌的SQL数据库,您将受益于养成使用标准报价的习惯.

使用单引号的另一个便利好处是,字符串中的文字双引号字符不需要转义:

select * from tablename where fields like '%string "hi" %';
Run Code Online (Sandbox Code Playgroud)


小智 12

MySQL有字符串函数QUOTE,它应该解决这个问题:

  • 另请注意,“QUOTE”为字符串值添加了周围的单引号 (2认同)

nic*_*ckf 9

您可以使用mysql_real_escape_string.mysql_real_escape_string()不逃避%_,所以你应该逃脱MySQL的通配符(%_)分开.

  • [函数 *mysql_real_escape_string()* 在 PHP 5.5.0 中已弃用,并在 PHP 7.0.0 中删除](https://www.php.net/manual/en/function.mysql-real-escape-string.php) 。 (4认同)

Raú*_*eno 7

对于像这样的字符串,对我来说,最舒服的方法是将"或"加倍,如MySQL手册中所述:

有几种方法可以在字符串中包含引号字符:

A “'” inside a string quoted with “'” may be written as “''”.

A “"” inside a string quoted with “"” may be written as “""”.

Precede the quote character by an escape character (“\”).

A “'” inside a string quoted with “"” needs no special treatment and need not be doubled or escaped. In the same way, “"” inside a
Run Code Online (Sandbox Code Playgroud)

用"'"引用的字符串不需要特殊处理.

它来自http://dev.mysql.com/doc/refman/5.0/en/string-literals.html.