问题 使用@符号进行MySQL全文搜索会产生错误“语法错误,意外'@',期待$ end”


由于@(at符号),以下查询导致错误。删除后,查询将正常工作。我试图逃避@角色,但没有运气。

SELECT * FROM clients WHERE MATCH (form) AGAINST ('test@test.com' IN BOOLEAN MODE);

产生的错误是:

#1064 - syntax error, unexpected '@', expecting $end

请注意,我正在phpMyAdmin SQL控制台区域中测试这些查询,因此我的其他编程不会出现转义错误。

MySQL服务器是5.6.17版。

有任何想法吗?谢谢。


4558
2017-08-01 20:29


起源

这没有理由发生,除非你有一个 ' 某处已经在哪里 ....'test 关闭那个字符串。 - Marc B
@Mark B错误继续发生,如图所示。请注意,以下两个查询工作正常,但不适合我的目标:SELECT * FROM clients WHERE form LIKE'%test@test.com%'SELECT * FROM clients WHERE MATCH(form)AGAINST('“test @ test。 com“'在布尔模式中); - witoto
我运行查询,没有错误 - catalinetu
我怀疑它是mysql还是innodb。它可能是phpmyadmin填充的 ' 在某个地方的背景混合。就像我说的,你上面发布的sql在语法上是完美的。如果他们的系统上有适当的表/字段,它就不会搞砸任何其他人的系统。 - Marc B
我修复了同样的问题,(不是语法错误 - 只有当字符串中包含'@'时才会出现)并且通过更改为NATURAL LANGUAGE MODE而不是BOOLEAN MODE来修复。 - xd6_


答案:


这与INNODB FULLTEXT索引相关联。

它是作为以下组合引入的:

  1. InnoDB全文搜索不支持在单个搜索词上使用多个运算符

  2. @距离   此运算符仅适用于InnoDB表。它测试两个或多个单词是否都在相互指定的距离内开始,用单词测量。

http://dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html

# Running a test search for MATCH('+test{$ascii}test' IN BOOLEAN MODE) on all ASCII chars returns errors on:
40 (
41 )
64 @

MYSQL似乎将这些符号视为wordbreaks,我发现无法逃避并将其包含在实际查询中,因此我的解决方案是对符号进行拆分并将它们包含在一个组中,例如“test @ bar”==(+ test + bar)

# As a further test, running a search for MATCH('+{$ascii}' IN BOOLEAN MODE) returns errors for:
40 (
41 )
42 *
43 +
45 -
60 <
62 >
64 @
126 ~

这与MYSQL文档中的预期一样,是特殊的BOOLEAN修饰符

# As a testcase (Requires MYSQL 5.6+): 
CREATE TABLE `fulltext_innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
 `text` text COLLATE utf8_unicode_ci,
 PRIMARY KEY (`id`),
 FULLTEXT KEY `text` (`text`)
) ENGINE=InnoDB
INSERT INTO `fulltext_innodb` (`id`, `text`) VALUES (1, 'test@bar');

SELECT * FROM `fulltext_innodb` WHERE MATCH (`text`) AGAINST( '+test@bar’ IN BOOLEAN MODE )

#1064 - syntax error, unexpected '@', expecting $end

11
2017-09-22 10:58



这有什么解决方法吗? - AMB


似乎没有办法用任何其他角色替换“@”术语。删除“@”并将其后的字符串添加到搜索中是我到目前为止找到的最佳解决方法。 这意味着

$mail = 'test@test.com';
$mail = str_replace("@", " +", $mail); //replace the @ that causes the problem
$query = "SELECT * FROM clients WHERE MATCH (form) AGAINST ('$mail' IN BOOLEAN MODE)'; //query with replaced mail address

应该带来所需的结果。

另一种方法是像处理它一样处理它 这个帖子 包含与另一个好的解决方法类似的问题。


0
2017-09-11 07:35