当 LIKE 条件包含多个非通配符时,准备查询无法获得 return 结果

Prepare query fails to return results when LIKE condition contains more than one non-wildcard character

我正在尝试使用准备好的语句搜索 table 用户。当搜索字符串包含多个字符或看似随机的字符时,不会return 编辑任何结果(即onn 失败但n 成功)。数据库中的数据应该 return 至少有一个关于我使用过的测试查询的结果 returns none。我不确定它是否与字符长度有关,但我尝试过的每个具有多个字符的搜索查询都将无法 return 结果,而它应该至少有一个结果。

我尝试了多种形式的查询,但都没有成功。我调整了 table 和字段的排序规则以添加不区分大小写。我搜索过类似的帖子,但找不到。我也查看了 MySQL preparelike 文档。我最初开始使用 PHP PDO 连接进行更复杂的查询,但已将其缩小为简单的 SELECT 并将其隔离到 MySQL prepare.


*所有这些查询都在 MySQL Workbench

中执行
PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

预期:特雷弗,布卢姆,特雷弗布卢姆
收到:
*我偶然发现了这个案例。我不确定为什么单个 n 可以工作,而单个 o 却不行。


PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'nn';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

预期: 安娜,霍根,安娜霍根
收到:


PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'n';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;
deallocate prepare stm;

预期: 匹配 %n%
的多个结果 收到: 预期结果


我也试过去掉CONCAT('%',?,'%'),用?代替,把@searchQuery改成%<query>%,结果和上面一样。

据我所知,没有生成任何错误消息或异常日志。

对于 users table 以及适用的列,

Charset/Collation 设置为 utf8utf_general_ci

下面是SHOW VARIABLES LIKE "%version%"

的结果

'innodb_version', '5.7.26'
'protocol_version', '10'
'slave_type_conversions', ''
'tls_version'、'TLSv1,TLSv1.1'
'version', '5.7.26-0ubuntu0.16.04.1-log'
'version_comment', '(Ubuntu)'
'version_compile_machine'、'x86_64'
'version_compile_os'、'Linux'

列名不能使用 ? 占位符。占位符用于代替值,它们将替换为您在执行语句时提供的文字值。

写的时候

PREPARE stm FROM "SELECT firstName, lastName, displayName FROM `users` WHERE ? LIKE CONCAT('%',?,'%') ORDER BY ? asc";
SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
EXECUTE stm USING @searchCol, @searchQuery, @orderBy;

它执行的查询是:

SELECT firstName, lastName, displayName 
FROM `users` 
WHERE 'firstName' LIKE CONCAT('%','o','%') 
ORDER BY 'lastName' asc

它不是在测试 firstName 列,而是将其作为文字字符串进行测试,这永远不会是真的,因为 firstName 中没有 o。而且它也不是按列排序的;它按常量排序,这意味着任何顺序。

您需要使用普通连接来替换列名,而不是占位符。

SET @searchCol = 'firstName';
set @searchQuery = 'o';
set @orderBy = 'lastName';
PREPARE stm FROM CONCAT("
    SELECT firstName, lastName, displayName 
    FROM `users` 
    WHERE ", @searchCol, " LIKE CONCAT('%',?,'%') 
    ORDER BY ", @orderBy, " asc");
EXECUTE stm USING @searchQuery;