例如:
select * from tablename where fields like "%string "hi" %";
错误:
您的SQL语法有误;请查阅与您的MySQL服务器版本相对应的手册,以获取正确使用语法的信息 near 'hi" "' at line 1
我该如何构建这个查询?
例如:
select * from tablename where fields like "%string "hi" %";
错误:
您的SQL语法有误;请查阅与您的MySQL服务器版本相对应的手册,以获取正确使用语法的信息 near 'hi" "' at line 1
我该如何构建这个查询?
本答案提供的信息可能会导致不安全的编程实践。
此处提供的信息高度依赖于MySQL配置,包括(但不限于)程序版本、数据库客户端和使用的字符编码。
请参见http://dev.mysql.com/doc/refman/5.0/en/string-literals.html
MySQL识别以下转义序列。 \0 ASCII NUL(0x00)字符。 \' 单引号(“'”)字符。 \" 双引号(“"”)字符。 \b 退格字符。 \n 换行符(LF)。 \r 回车字符。 \t 制表符。 \Z ASCII 26(Control-Z)。请参见表格后面的注释。 \\ 反斜杠(“\”)字符。 \% “%”字符。请参见表格后面的注释。 \_ “_”字符。请参见表格后面的注释。
所以你需要:
select * from tablename where fields like "%string \"hi\" %";
虽然正如Bill Karwin在下面指出的那样,使用双引号作为字符串分隔符并不是标准SQL,因此最好使用单引号。这样可以简化事情:
select * from tablename where fields like '%string "hi" %';
我已经在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();
}
在字符串分隔符中应该使用单引号。 单引号是标准的 SQL 字符串分隔符,而双引号是标识符分隔符(因此您可以在表或列名称中使用特殊单词或字符)。
在MySQL中,默认情况下双引号作为字符串分隔符工作(非标准方式),除非您设置了 ANSI
SQL 模式。 如果您曾经使用过其他品牌的 SQL 数据库,那么养成使用标准引号的习惯将对您有益。
使用单引号的另一个便捷之处在于您字符串内的双引号字符不需要转义:
select * from tablename where fields like '%string "hi" %';
\\
。 - Peter MortensenMySQL拥有字符串函数QUOTE,它应该可以解决这个问题。
LIKE
的%
字符,所以它几乎没什么用处。 - Peter V. MørchQUOTE
会为字符串值添加单引号。 - FlameStorm对于这样的字符串,我个人觉得最舒适的方式是使用两个相同的 ' 或 ",如MySQL手册所述:
来自于 http://dev.mysql.com/doc/refman/5.0/en/string-literals.html。There are several ways to include quote characters within a string:
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
Strings quoted with “'” need no special treatment.
mysql_real_escape_string()
函数不会转义 %
和 _
,所以您需要单独转义 MySQL 通配符(%
和 _
)。为了测试如何在MySQL终端中插入双引号,您可以使用以下方法:
TableName(Name,DString) -> Schema
insert into TableName values("Name","My QQDoubleQuotedStringQQ")
插入值后,您可以使用双引号或单引号更新数据库中的值:
update table TableName replace(Dstring, "QQ", "\"")
如果您在字符串搜索中使用变量,则mysql_real_escape_string()
非常适合您。只是我的建议:
$char = "and way's 'hihi'";
$myvar = mysql_real_escape_string($char);
select * from tablename where fields like "%string $myvar %";