【问题标题】:Prepare query fails to return results when LIKE condition contains more than one non-wildcard character当 LIKE 条件包含多个非通配符时,准备查询无法返回结果
【发布时间】:2019-07-02 21:21:10
【问题描述】:

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

我尝试了多种形式的查询,但都没有成功。我已经调整了表格和字段的排序规则以添加不区分大小写。我搜索过类似的帖子,但找不到。我也浏览了 MySQL preparelike 文档。我最初使用 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>%,但结果与上述相同。

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

users 表和适用列的字符集/排序规则设置为 utf8utf_general_ci

下面是SHOW VARIABLES LIKE "%version%"的结果

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

【问题讨论】:

  • 列名不能使用占位符,只能用于表达式。
  • @Barmar 我知道我错过了一些简单的东西!谢谢!

标签: mysql prepared-statement sql-like


【解决方案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 列,而是将它作为文字字符串进行测试,这永远不会是真的,因为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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-28
    相关资源
    最近更新 更多