9

我需要从数据库中找到Lämmönmyyntipalvelut这个词。只是,在数据库中,它位于一个字段中,其值是一个 PHP 数组,使用 json_encode() 转换为 JSON,因此特殊字符被写入十六进制 unicode。

所以我的查询是

SELECT * FROM table WHERE (services LIKE '%Lämmönmyyntipalvelut%')

没有结果。没有惊喜。接下来,使用转换的特殊字符进行查询:

SELECT * FROM table WHERE (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%')

没有结果,我想知道为什么。接下来我测试了仅查询特殊字符:

SELECT * FROM table WHERE (services LIKE '%\u00e4%')

找到了应该找到的东西。接下来我开始添加东西(从 L 开始),看看哪里出了问题:

SELECT * FROM table WHERE (services LIKE '%L\u00e4%')

没有结果。另一个测试:

SELECT * FROM table WHERE (services LIKE '%\u00e4mm%')

找到了应该找到的东西。

所以我的结论是反斜杠在某种程度上把事情搞砸了,但我不明白怎么做?

编辑:

服务领域的具体内容:

["Neuvonta","L\u00e4mm\u00f6nmyyntipalvelut",
"Mets\u00e4-\/energiapuunkorjuupalvelut"]

准确查询:

SELECT id, uid, company_name, services, logo FROM rekisteroeidy_toimijaks 
WHERE 
    (services LIKE '%L\u00e4mm\u00f6nmyyntipalvelut%' AND 
    services LIKE '%Mets\u00e4-\/energiapuunkorjuupalvelut%') 
ORDER BY company_name ASC

我添加了一些换行符以提高可读性。

4

3 回答 3

13

我完全不知道为什么,但是三重转义有帮助!

好吧,这只是双重转义,但它确实有效,原因如下:在 MySQL 中,当您使用LIKE运算符时,涉及到第二层转义。

services LIKE '%L\\\\u00e4mm\\\\u00f6n%'

解析 MySQL 字符串文字可以让您与 LIKE-query 进行比较%L\\u00e4mm\\u00f6n%。因为 MySQL\在 LIKE 查询中将其视为转义,所以它实际上将匹配包含L\u00e4mm\u00f6n.

这样做的原因是您可以将字符串与包含文字%_字符的查询表达式进行匹配。例如,如果我想在一列中搜索文字字符串,100%我可以将其与100\%(在查询中写为'100\\%'

不幸的是,MySQL 使用反斜杠进行 LIKE 查询转义和字符串文字转义,特别是考虑到您可能正在使用一种也使用它们的封闭编程语言编写,最终得到实际的三重编码,看起来像"services LIKE '%L\\\\\\\\u00e4mm\\\\\\\\u00f6n%'"- 啊!

不幸的是,这种行为不符合 ANSI SQL,并且在任何其他数据库中都不起作用。ANSI SQL 表示默认情况下 LIKE 查询中没有转义字符,因此如果您想匹配文字%或者_您必须通过指定自己的转义字符来选择加入,例如:

something LIKE '100=%' ESCAPE '='

为了跨数据库的兼容性,最好总是使用LIKE...ESCAPE形式,并选择可怕的反斜杠以外的东西!(除此之外 - MySQL 用于 SQL 字符串文字转义的反斜杠也不符合 ANSI!但您可以使用 NO_BACKSLASH_ESCAPES sql_mode 设置关闭这种不当行为。)

可能更好的主意是拆分services成第二个表,而不是将它们压缩成单个字符串列 - 即。把你的模式放在第一范式中。然后,您可以简单地查找单个值,而不必进行缓慢的全表扫描子字符串匹配。

于 2012-11-11T00:51:52.290 回答
3

反斜杠是元字符,MySQL 是这样理解的:“删除下一个字符,不要将其解析为元字符”。

所以你需要转义反斜杠:

SELECT * FROM table WHERE (services LIKE '%L\\u00e4%')

现在,MySQL 将用“\”替换“\\”(第一个反斜杠是用于转义第二个反斜杠的元字符)

于 2012-11-08T10:31:08.260 回答
1

I have absolutely no idea why, but triple escaping helps!

SELECT id, uid, company_name, services, logo
FROM rekisteroeidy_toimijaks
    WHERE (
    services LIKE  '%L\\\\u00e4mm\\\\u00f6n%'
)
ORDER BY company_name ASC 
LIMIT 0 , 30
于 2012-11-08T11:19:09.983 回答