我正在尝试使用准备好的语句搜索用户表。当搜索字符串包含多个字符或看似随机的字符时,不会返回任何结果(即o
和nn
失败,但n
成功)。数据库中的数据应在我使用的测试查询中至少返回一个结果,但不返回任何结果。我不确定这与字符长度有关,但是我尝试过的每个搜索查询中有多个字符以上的查询都会在至少应有一个结果的情况下无法返回结果。
我尝试了很多形式的查询,但都没有碰到运气。我已经调整了表格和字段的排序规则,以增加区分大小写的能力。我搜索了类似的帖子,但找不到。我也阅读了MySQL prepare
和like
文档。最初,我开始使用PHP PDO连接进行更复杂的查询,但将其范围缩小到一个简单的SELECT
并将其隔离到MySQL准备中。
*所有这些查询都是在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;
预期: Trevor,Bloom,Trev Bloom
已收到:没有任何操作
*我偶然发现了这个案子。我不确定为什么单个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>%
的情况,但是结果与上面相同。
据我所知,不会生成任何错误消息或异常日志。
utf8
表以及适用的列的字符集/排序规则分别设置为utf_general_ci
和users
。
下面是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'
答案 0 :(得分:1)
列名不能使用?
占位符。占位符用于代替值,它们被执行语句时提供的文字值替换。
写作时
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
列,而是以文字字符串对其进行测试,这永远是不正确的,因为o
中没有firstName
。而且也不是按列排序;它是按常数排序的,这意味着任何顺序。
您需要使用普通串联来代替列名,而不是占位符。
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;