对于相同的值,对等号的Mysql字符串检查为false

时间:2012-04-13 07:52:05

标签: php mysql strlen

我的MySql有问题 我有一个表格,其中包含来自网站的解析信息。出现一个奇怪的字符串解释:

查询

select id, address from pagesjaunes_test where address = substr(address,1,length(address)-1)

返回一组值而不是

一开始我执行的函数为:

address = replace(address, '\n', '')
address = replace(address, '\t', '')
address = replace(address, '\r', '')
address = replace(address, '\r\n', '')
address = trim(address)

但问题仍然存在。

字段'address'的值有一些法语字符,但查询返回的值也只包含alfanumeric english chars。

另一个测试:我试图检查字符串的长度和...来自PHP的strlen()和来自MYSQL的LENGTH()显示不同的结果!在某处,差异是2个字符,某个字符为1个字符,没有特定的“规则”。

视觉我看不到任何空格或制表符或其他东西。

我修改了一个manualy的地址后(我删除了所有的字符串,我再次写了),问题解决了,但我有~6000个值,所以这不是一个解决方案:)

可能是什么问题?

我认为字符串可以作为“空字符”,但如何检测并删除它?

由于

P.S。 问题不仅仅是长度。我需要将此表与其他表连接,并使用检查字段'address'中的值是否等于的条件。即使字段具有相同的排序规则且表具有相同的排序规则,查询也会返回没有地址匹配的

E.g。

查询:

SELECT p.address,char_length(p.address) , r.address, char_length(r.address) 
FROM `pagesjaunes_test` p
LEFT JOIN restaurants r on p.name=r.name
WHERE  
p.postal_code=r.postal_code 
and p.address!=r.address
and p.phone='' 
and p.cuisines=''
LIMIT 10

所以: p.address!= r.address

结果是:

+-------------------------------------+------------------------+--------------------------+------------------------+
| address                             | char_length(p.address) | address                  | char_length(r.address) |
+-------------------------------------+------------------------+--------------------------+------------------------+
| Dupin Marc13 quai Grands Augustins  |                     34 | 13 quai Grands Augustins |                     24 |
| 39 r Montpensier                    |                     16 | 39 r Montpensier         |                     16 |
| 8 r Lord Byron                      |                     14 | 3 r Balzac               |                     10 |
| 162 r Vaugirard                     |                     15 | 162 r Vaugirard          |                     15 |
| 32 r Goutte d'Or                    |                     16 | 32 r Goutte d'Or         |                     16 |
| 2 r Casimir Périer                  |                     18 | 2 r Casimir Périer       |                     18 |
| 20 r Saussier Leroy                 |                     19 | 20 r Saussier Leroy      |                     19 |
| Senes Douglas22 r Greneta           |                     25 | 22 r Greneta             |                     12 |
| Ngov Ly Mey44 r Tolbiac             |                     23 | 44 r Tolbiac             |                     12 |
| 33 r N-D de Nazareth                |                     20 | 33 r N-D de Nazareth     |                     20 |
+-------------------------------------+------------------------+--------------------------+------------------------+

如您所见,“162 r Vaugirard”,“20 r Saussier Leroy”仅包含ASCII字符,长度相同但不等于!

3 个答案:

答案 0 :(得分:3)

也许看一下mysql文本字段的编码 - UTF8用2个字节对​​大部分字符进行编码 - 只有一小部分UTF8(例如ASCII字符)用一个字节编码。

MySQL知道UTF8并且数量正确。 PHP文本函数不支持UTF8并计算字节本身。

因此,如果PHP的数量超过MYSQL,这可能就是原因,您可以查看utf8decode。

来自萨尔茨堡的消息!

答案 1 :(得分:1)

official documentation说:

  

返回字符串str的长度,以字节为单位。多字节字符计为多个字节。这意味着对于包含五个双字节字符的字符串,LENGTH()返回10,而CHAR_LENGTH()返回5.

所以,请改用CHAR_LENGTH:)

select id, address from pagesjaunes_test
where address = substr(address, 1, char_length(address) - 1)

答案 2 :(得分:0)

最后,我发现了问题。将更改后的归类更改为ascii_general_ci后,所有非ascii字符都转换为"?"。一些空格也被"?"取代。检查初始值后,MySQL的函数ORD()为这些空格返回160(而不是32)。所以,

UPDATE pagesjaunes_test SET address = TRIM(REPLACE(REPLACE(address, CHAR(160), ' '), '  ',' ')

解决了我的问题。