Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:查询unicode实体_Mysql_Unicode - Fatal编程技术网

MySQL:查询unicode实体

MySQL:查询unicode实体,mysql,unicode,Mysql,Unicode,我需要从数据库中找到单词Lämmönmyyntipalvelut。只是在数据库中,它位于一个字段中,该字段的值是一个PHP数组,使用JSON_encode()将其转换为JSON,因此特殊字符被拼凑成十六进制unicode 所以我的问题是 SELECT * FROM table WHERE (services LIKE '%Lämmönmyyntipalvelut%') 没有结果。不足为奇。接下来,使用转换的特殊字符进行查询: SELECT * FROM table WHERE (service

我需要从数据库中找到单词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

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

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

因此,您需要避开反斜杠:

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

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

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

SELECT id, uid, company_name, services, logo
FROM rekisteroeidy_toimijaks
    WHERE (
    services LIKE  '%L\\\\u00e4mm\\\\u00f6n%'
)
ORDER BY company_name ASC 
LIMIT 0 , 30

我完全不知道为什么,但三倍逃跑有帮助

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

services LIKE '%L\\\\u00e4mm\\\\u00f6n%'
通过分析该MySQL字符串文本,可以与类似的查询进行比较
%L\\u00e4mm\\u00f6n%
。由于MySQL将LIKE查询中的
\
视为转义,因此实际上将匹配包含
L\u00e4mm\u00f6n
的文本字符串

这样做的原因是,您可以将字符串与包含文字
%
字符的查询表达式进行匹配。例如,如果我想在一列中搜索文字字符串
100%
,我可以将其与
100\%
(在查询中写为
'100\\%'
)匹配,并确保我得到的是100%,而不是任何以100开头的字符串

不幸的是,MySQL同时使用反斜杠作为其类似的查询转义和字符串文字转义,特别是考虑到您可能正在使用一种封闭的编程语言编写它们,最终使用了实际的三重编码,这看起来像是
“像“%L”\u00e4mm\u00f6n%这样的服务”
-argh

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

something LIKE '100=%' ESCAPE '='
为了实现跨数据库的兼容性,最好始终使用
类似的
转义
表单,并选择除可怕的反斜杠以外的内容!(旁白-MySQL用于SQL字符串文字转义的反斜杠也不符合ANSI!但您可以使用无反斜杠转义SQL模式设置来关闭这种错误行为。)


可能更好的办法是将
服务
分解到第二个表中,而不是将它们压缩到一个字符串列中——即,将您的模式放在第一个标准形式中。然后,您可以获得单个值的简单查找,而不必进行缓慢的全表扫描子字符串匹配。

不幸地没有帮助。真的吗?在“精确查询”中,反斜杠不会转义。像这样逃避每一个反斜杠能解决问题吗从rekisteroeidy toimijaks中选择id、uid、公司名称、服务、徽标,其中(像“%L\\u00e4mm\\u00f6nmyyntipalvelut%”这样的服务和像“%Mets\\u00e4-\\\/energiapuunkorjuupalvelot%”这样的服务)按公司名称按实际顺序订购,听起来很奇怪。从逻辑上讲,你的答案是正确的,有道理的,但我试过了,结果不起作用。显示
json\u encode()
d结果。你是指服务字段的内容吗?是的,也许有人可以从中看出问题所在。从我看来,文斯的答案应该有效,如果你把每个反斜杠加倍,`\`我也应该有效,是的,但仍然没有:/这听起来像是用php、java或其他语言来实现的。我很确定,文斯的回答没有这个。所以,如果是这样的话,你应该这样做。但是当我使用phpMyAdmin得到完全相同的行为时,这怎么可能取决于我使用的语言(正确的是PHP)?我只是在命令行mysql中尝试了这个,你是对的。我已经更正了,很抱歉混淆了。因为当您将SQL语句字符串放入PHP字符串中时,该字符串被多次转义:第一次由PHP(字符串声明)转义,第二次由MySQL转义。由于PHP和许多其他语言(Java、C#…)使用反斜杠作为转义字符,您将遇到此问题,需要双重转义。由于某些原因,转义在我的数据库中根本不起作用。我尝试了所有带/不带二进制的组合,并从1次转义到8次。可能必须使用utf8mb4\u unicode\u ci排序规则。让示例正常工作的唯一方法是:
SELECT*FROM表,其中包含二进制CONCAT(“%L”,UNHEX('c3a4'),'mm%”等服务
还需要进行二进制加法,否则结果也会匹配“Lamm”,而不需要在a@KapiteinWitbaard上进行分录。这是匹配实际
字符的一种方法(假设使用UTF-8排序规则),前提是您不能在任何环境中直接键入
%Lämm%
。OP并不是这么做的——他们试图在一些序列化JSON中匹配实际的反斜杠,而不是字面的
ä
。JSON有
\unnn
转义以引用Unicode字符;SQL文本本身不支持。@Kapitein