当 LIKE 条件包含多个非通配符时,准备查询无法获得 return 结果
Prepare query fails to return results when LIKE condition contains more than one non-wildcard character
我正在尝试使用准备好的语句搜索 table 用户。当搜索字符串包含多个字符或看似随机的字符时,不会return 编辑任何结果(即o
和nn
失败但n
成功)。数据库中的数据应该 return 至少有一个关于我使用过的测试查询的结果 returns none。我不确定它是否与字符长度有关,但我尝试过的每个具有多个字符的搜索查询都将无法 return 结果,而它应该至少有一个结果。
我尝试了多种形式的查询,但都没有成功。我调整了 table 和字段的排序规则以添加不区分大小写。我搜索过类似的帖子,但找不到。我也查看了 MySQL prepare
和 like
文档。我最初开始使用 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 设置为 utf8
和 utf_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;
我正在尝试使用准备好的语句搜索 table 用户。当搜索字符串包含多个字符或看似随机的字符时,不会return 编辑任何结果(即o
和nn
失败但n
成功)。数据库中的数据应该 return 至少有一个关于我使用过的测试查询的结果 returns none。我不确定它是否与字符长度有关,但我尝试过的每个具有多个字符的搜索查询都将无法 return 结果,而它应该至少有一个结果。
我尝试了多种形式的查询,但都没有成功。我调整了 table 和字段的排序规则以添加不区分大小写。我搜索过类似的帖子,但找不到。我也查看了 MySQL prepare
和 like
文档。我最初开始使用 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 设置为 utf8
和 utf_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;