【问题标题】:How to properly use Wildcard with CONCAT如何在 CONCAT 中正确使用通配符
【发布时间】:2019-05-31 07:32:00
【问题描述】:

(剧透:标题与代码的问题无关。

我正在创建一个实时搜索系统,只是为了向用户展示我的网站上已经列出的可能的事件类型。在我的猜测中,我可能在通配符绑定方面遇到了一个我看不到的错误。

我尝试使用不同类型的“WHERE LIKE”语句,但其中大多数根本不起作用。比如我尝试使用占位符查询(问号),但根本不起作用。如果我在我的数据库上手动运行这个查询,我会得到我期望的结果。

这是我的代码的样子,变量 $q 是使用 $_GET 方法获得的。

$query = $pdo->prepare('SELECT DISTINCT EventCategory FROM Events
             WHERE EventCategory LIKE CONCAT(\'%\',:q,\'%\')');
$query->bindParam(":q", $q);
$query->execute();
$row = $query->fetch(PDO::FETCH_ASSOC);
while ($row = $query->fetchObject()) {
    echo "<div>  $row->EventCategory </div>";
}

预期结果将是:如果 $q 等于 n,则返回会议和夜生活。当 $q 等于 ni 时,只返回 Nightlife。

搜索不区分大小写,N 和 n 被同等对待。

SHOW CREATE TABLE 事件查询返回以下内容:

  CREATE TABLE `Events` (
 `ID` int(11) NOT NULL AUTO_INCREMENT,
 `Name` varchar(100) NOT NULL,
 `Image` varchar(600) NOT NULL,
 `Date` date NOT NULL,
 `Description` varchar(1200) NOT NULL,
 `SpacesAvailable` int(11) NOT NULL,
 `EventCategory` varchar(50) NOT NULL,
 `Trending` varchar(30) DEFAULT NULL,
 `TrendingID` int(255) NOT NULL,
 `Sale` int(255) NOT NULL,
 PRIMARY KEY (`ID`)
)DEFAULT CHARSET=latin1

显示网站运作的图片:https://imgur.com/a/yP0hTm3 如果您正在查看图像,请从下到上查看。谢谢

【问题讨论】:

  • 您可能会在不需要的地方获得额外的报价。试试WHERE EventCategory LIKE :qbindParam(':q', '%' . $q . '%');
  • $q = $_GET['something']; 是如何分配$q 的? concat 的用法看起来是正确的。
  • family fun 也应该与n 搜索一起返回。
  • n 是最后一个字母。您在图片中搜索了n。如果问题与排序规则/字符集相关,我们应该在数据库中得到相同的结果。能否展示一下在 DB 界面中执行 SELECT DISTINCT EventCategory FROM Events WHERE EventCategory LIKE CONCAT('%', 'n','%') 时会发生什么?
  • 尝试将查询存储到变量中,然后转储变量,以说服自己查询是正确的。如果您在 phpmyadmin 或其他一些 sql 客户端程序中键入等效查询会发生什么?

标签: php mysql pdo collation


【解决方案1】:

我怀疑EventCategory 列中的默认排序规则区分大小写。这就是 NiniNightlife 中不匹配的原因。

试试这个查询。

'SELECT DISTINCT EventCategory FROM Events WHERE EventCategory COLLATE utf8_general_ci LIKE CONCAT(\'%\',:q,\'%\')'

或者,如果您列的字符集不是 unicode 而是 iso8859-1,试试这个:

'SELECT DISTINCT EventCategory FROM Events WHERE EventCategory COLLATE latin1_general_ci LIKE CONCAT(\'%\',:q,\'%\')'

This explains how 在 MySQL 上查找可用的字符集和排序规则。

How to change collation of database, table, column? 解释了如何更改表或列的默认排序规则。这通常是一个好主意,因为排序规则已包含在索引中。

【讨论】:

  • 可悲的是,它根本不起作用。虽然,我的 unicode 是 iso8859-1,因为第一个选项不起作用;P 请再次检查我的问题,因为我已经按照您的需要对其进行了更新。谢谢。
  • latin1 的默认值为latin1_swedish_ci,因此它是“不区分大小写”的。因此添加COLLATE... 不会是一个解决方案。 (请参阅 SHOW COLLATION LIKE 'latin1%'; 以获取默认值。)
【解决方案2】:

问题不在于LIKE,而在于PHP 和PDO。查看代码中 $row 的 3 个冲突用法:

$row = $query->fetch(PDO::FETCH_ASSOC);
while ($row = $query->fetchObject()) {
echo "<div>  $row->EventCategory </div>"; }

然后查看文档和示例。 (对不起,我不会给你答案;你需要学习才能理解它。)

【讨论】:

  • 亲爱的瑞克我的救星!我实际上去看了文档,我“认为”我发现了错误。我基本上执行了两次而不是一次,我的解决方案是在 while 循环中声明 fetchObject,并删除顶部的,因为 fetchObject 已经做了“fetch”所做的事情......所以我的错误是“重复”。谢谢!
【解决方案3】:

作为对 O.Jones 全面回答的补充,另一种更简单的解决方案是只执行不区分大小写的搜索,例如:

'SELECT DISTINCT EventCategory 
 FROM Events 
 WHERE UPPER(EventCategory) LIKE CONCAT(\'%\',UPPER(:q),\'%\')'

【讨论】:

  • 非常感谢您的回复!但可悲的是,上述解决方案不起作用。完全没有变化。相同的最终结果。虽然感谢您的时间! :D
  • 不,使用列的排序规则。
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-03
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多