使用LIKE进行mysql二进制字段查找有一个bug

问题描述 投票:0回答:1

当使用

01HRS49374C1EAGTPKTJ0JVT1P
查询时,我对 BINARY(16) 类型(引擎盖下的 ULID)和特定 ULID
018e32448ce4605ca86ad3d4812de836
(十六进制
LIKE
)有问题。 LIKE 查询适用于其他 ULID,但不适用于此特定 ULID。

由于它是 ULID,长度始终为 16 字节,因此字段大小不是问题。

下面代码中的最后一个

SELECT 语句返回空结果!为什么?


CREATE TABLE IF NOT EXISTS new_table (
    id BINARY(16) PRIMARY KEY NOT NULL,
    name VARCHAR(255)
);

INSERT INTO new_table SET id = UNHEX("018e321f579997e1f2a907a72b98f965"), name = "this works fine";
INSERT INTO new_table SET id = UNHEX("018e32448ce4605ca86ad3d4812de836"), name = "try find this using LIKE";

SELECT HEX(id), name FROM new_table WHERE id LIKE UNHEX("018e321f579997e1f2a907a72b98f965");
SELECT HEX(id), name FROM new_table WHERE id LIKE UNHEX("018e32448ce4605ca86ad3d4812de836");


mysql binary sql-like ulid
1个回答
1
投票

mysql> SELECT HEX(id), name FROM new_table WHERE id LIKE UNHEX("018e32448ce4605ca86ad3d4812de836") ESCAPE '@'; +----------------------------------+--------------------------+ | HEX(id) | name | +----------------------------------+--------------------------+ | 018E32448CE4605CA86AD3D4812DE836 | try find this using LIKE | +----------------------------------+--------------------------+

如果我们禁用反斜杠作为元字符,它也可以工作:

mysql> set sql_mode='NO_BACKSLASH_ESCAPES'; Query OK, 0 rows affected (0.01 sec) mysql> SELECT HEX(id), name FROM new_table WHERE id LIKE UNHEX("018e32448ce4605ca86ad3d4812de836"); +----------------------------------+--------------------------+ | HEX(id) | name | +----------------------------------+--------------------------+ | 018E32448CE4605CA86AD3D4812DE836 | try find this using LIKE | +----------------------------------+--------------------------+

于是我尝试在客户端查看二进制字符串:

% mysql --skip-binary-as-hex test mysql> select UNHEX("018e32448ce4605ca86ad3d4812de836"); +-------------------------------------------+ | UNHEX("018e32448ce4605ca86ad3d4812de836") | +-------------------------------------------+ | ?2D??`\?j?ԁ-?6 | +-------------------------------------------+ ^

有反斜杠。

关键在于

LIKE

对字符串中的某些字符应用了一些特殊含义,例如反斜杠、

_
%
如果您对随机十六进制字符串进行 UNHEX,您不知道这些字节是否会巧合地成为 

LIKE

特有的字符之一。

结论:这不是一个错误。

LIKE

不是适合您搜索的比较运算符。

在您的示例中,使用 

=

就可以了,因为您正在检查字符串是否相等,而不是使用

LIKE
进行模式匹配。
这有效:

mysql> SELECT HEX(id), name FROM new_table WHERE id = UNHEX("018e32448ce4605ca86ad3d4812de836"); +----------------------------------+--------------------------+ | HEX(id) | name | +----------------------------------+--------------------------+ | 018E32448CE4605CA86AD3D4812DE836 | try find this using LIKE | +----------------------------------+--------------------------+

© www.soinside.com 2019 - 2024. All rights reserved.