我发现自己在 PDO 中处于一个非常奇怪的境地。从 PhP 调用时不想执行查询,但从 HeidiSQL 调用时它会执行。
错误在标题中。
来自语句 debugDumpParams 的 SQL 查询:
SELECT s_id AS id,
s_title AS title,
genre.g_name AS genreName,
accounts.ac_public_name AS producerName,
s_price AS price,
DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') AS lastModifiedDate,
DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') AS addedDate,
s_downloads AS downloads,
s_sales AS sales,
s_rating AS rating,
s_status AS STATUS
FROM song
JOIN accounts ON accounts.ac_id = song.s_producer
JOIN genre ON genre.g_id = song.s_genre
WHERE 1=1 AND genre.g_id = '1'
ORDER BY s_status ASC, s_added_date DESC
LIMIT 0, 5;
接下来是我在查询字符串中添加genre.g_id = :id 的部分
if(isset($filterData["genreId"]) && $filterData["genreId"] !== ""){
$queryString .= " AND genre.g_id = :genreId";
}
在我绑定它的地方
if(isset($filterData["genreId"]) && $filterData["genreId"] !== ""){
$genreParam = $filterData["genreId"];
$stmt->bindParam('genreId', $genreParam);
}
在这两种情况下都设置了 $filterData["genreId"] 并且它有一个值,所以 if 没有问题。如果 $filterData["genreId"] 为空或未设置,则查询没有问题。
并且错误: SQLSTATE[42S22]: Column not found: 1054 Unknown column \'genre.g_id\' in \'where clause\'
但是等等,还有更多。如果我放genre.g_id2 而不是genre.g_id,它将如下所示:
if(isset($filterData["genreId"]) && $filterData["genreId"] !== ""){
$queryString .= " AND genre.g_id2 = :genreId";
}
现在它甚至达不到 $stmt->debugDumpParams(); 它给出的只是这个错误: SQLSTATE[42S22]: Column not found: 1054 Unknown column \'genre.g_id2\' in \'where clause\ ,没有像以前那样的查询。
表中存在 100% 列。此查询的类似问题:
SELECT s_id AS id,
s_title AS title,
genre.g_name AS genreName,
accounts.ac_public_name AS producerName,
s_price AS price,
DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') AS lastModifiedDate,
DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') AS addedDate,
s_downloads AS downloads,
s_sales AS sales,
s_rating AS rating,
s_status AS STATUS
FROM song
JOIN accounts ON accounts.ac_id = song.s_producer
JOIN genre ON genre.g_id = song.s_genre
WHERE 1=1 AND accounts.ac_id = '999999'
ORDER BY s_status ASC, s_added_date DESC
LIMIT 0, 5;
似乎问题仅出在与表song
JOIN 一起使用的表中的列上。
下一个查询完美运行。
SELECT s_id AS id,
s_title AS title,
genre.g_name AS genreName,
accounts.ac_public_name AS producerName,
s_price AS price,
DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') AS lastModifiedDate,
DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') AS addedDate,
s_downloads AS downloads,
s_sales AS sales,
s_rating AS rating,
s_status AS STATUS
FROM song
JOIN accounts ON accounts.ac_id = song.s_producer
JOIN genre ON genre.g_id = song.s_genre
WHERE 1=1 AND s_status = '0'
ORDER BY s_status ASC, s_added_date DESC
LIMIT 0, 5;
2天,没有解决方案。我发现的大多数解决方案都是再次检查该列是否确实存在:| 有没有人对这个特定问题有更好的解决方案?
目标是选择 g_id 与我传递给它的值相等的数据。
我如何创建查询字符串:
$queryString = "SELECT s_id as id,
s_title as title,
genre.g_name as genreName,
accounts.ac_public_name as producerName,
s_price as price,
DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') as lastModifiedDate,
DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') as addedDate,
s_downloads as downloads,
s_sales as sales,
s_rating as rating,
s_status as status
FROM song
JOIN accounts on accounts.ac_id = song.s_producer
JOIN genre on genre.g_id = song.s_genre
WHERE 1=1 ";
然后在一个函数中我添加这个
if(isset($filterData["genreId"]) && $filterData["genreId"] !== ""){
$queryString .= " AND genre.g_id = :genreId";
}
然后我这样做
$queryString .= " ORDER BY s_status asc, s_added_date desc";
$queryString .= " LIMIT :offset, :limit;";
最后
$stmt = $dbConnector->getConnection()->prepare($queryString);
这是与问题相关的部分。我不能发布整个功能,它真的很长。
这用于根据某些输入或输入组合搜索数据。整个 DAO 类真的很大 :)
操作系统:Windows 10,PhP 版本:7.2.19,Apache 版本:2.4.35,MariaDB 版本:10.4 Heidi SQL:10.2.0.5599
再编辑一个:
如果我在第一次声明它时在 queryString 中添加列:
$queryString = "SELECT s_id as id,
s_title as title,
genre.g_name as genreName,
accounts.ac_public_name as producerName,
s_price as price,
DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') as lastModifiedDate,
DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') as addedDate,
s_downloads as downloads,
s_sales as sales,
s_rating as rating,
s_status as status
FROM song
JOIN accounts on accounts.ac_id = song.s_producer
JOIN genre on genre.g_id = song.s_genre
WHERE 1=1 AND genre.g_id = :genreId";
$queryString = $this->filterDataQuery($queryString, $filterData, "songs");
$queryString .= " ORDER BY s_status asc, s_added_date desc";
$queryString .= " LIMIT :offset, :limit;";
$stmt = $dbConnector->getConnection()->prepare($queryString);
$genreParam = $filterData["genreId"];
$stmt->bindParam(':genreId', $genreParam);
而不是在 $this->filterDataQuery($queryString, $filterData, "songs"); 当我基于选定的过滤器构建 queryString 时,它工作得很好。这是现在从浏览器控制台中选择的:
SELECT s_id AS id,
s_title AS title,
genre.g_name AS genreName,
accounts.ac_public_name AS producerName,
s_price AS price, DATE_FORMAT(s_last_modified_date, '%d/%m/%Y %H:%i:%s') AS lastModifiedDate, DATE_FORMAT(s_added_date, '%d/%m/%Y %H:%i:%s') AS addedDate,
s_downloads AS downloads,
s_sales AS sales,
s_rating AS rating,
s_status AS STATUS
FROM song
JOIN accounts ON accounts.ac_id = song.s_producer
JOIN genre ON genre.g_id = song.s_genre
WHERE 1=1 AND genre.g_id = '1'
ORDER BY s_status ASC, s_added_date DESC
LIMIT 0, 5;
这个和第一个不一样吗?因为它是。我瞎了?