簡體   English   中英

SQLSTATE [42S22]:未找到列:1054 未知列 PhP PDO MariaDB10

[英]SQLSTATE[42S22]: Column not found: 1054 Unknown column PhP PDO MariaDB10

我發現自己在 PDO 處於一個非常奇怪的境地。 從 PhP 調用時不想執行查詢,但從 HeidiSQL 調用時它會執行。

錯誤在標題中。

SQL 從語句 debugDumpParams 查詢:

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 子句\,沒有像以前那樣的查詢。

表中存在 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天,沒有解決方案。 我發現的大多數解決方案是再次檢查該列是否確實存在:| 有沒有人對這個特定問題有更好的解決方案?

目標是 select 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 ";

然后在 function 我添加這個

 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);

這是與問題相關的部分。 發不了整個function,實在是太長了。

這用於根據某些輸入或輸入組合搜索數據。 整個DAO class 真的很大:)

OS: Windows 10, PhP version: 7.2.19, Apache version: 2.4.35, MariaDB version: 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:

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;

這個和第一個不一樣嗎? 因為它是。 我瞎了?

在重讀了你的第一篇文章數十次並在本地測試了各種正常的東西而沒有出現相同的錯誤之后,我認為filterDataQuery()中的$stmt變量包含與此處發布的完全不同的查詢。 它只是不包括錯誤消息中顯示的表格genre 如果您沒有使用 function,請查看倒數第二個代碼塊,一切正常(如果我理解正確的話)。

同樣根據顯示的代碼,我不明白您將如何調用filterDataQuery()向查詢字符串添加條件,並將參數直接綁定到稍后准備的語句 object ,因此那里不可用(或不是那個你會期望)。

為了證明我的理論我的完整測試代碼,仍然使用這個 db-fiddle

ini_set('display_errors', 1);
error_reporting(E_ALL);

$DB_USER = '*****';
$DB_PASS = '*****';
$db = new PDO('mysql:host=localhost;dbname=testing.project', $DB_USER, $DB_PASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);

$select = '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 = ' WHERE genre.g_id = :genreId';
$order = ' ORDER BY s_status ASC, s_added_date DESC';
$limit = ' LIMIT 0, 5';

// No problemo:
$sql = $select . $where . $order . $limit;
$stmt = $db->prepare($sql);
$genreId = 1;
$stmt->bindParam(':genreId', $genreId);
$stmt->execute();

// Trigger error column not found, $stmt containing an unexpected query:
$select = 'SELECT * FROM `song`';
$sql = $select . $where . $order . $limit;
$stmt = $db->prepare($sql);
$genreId = 1;
$stmt->bindParam(':genreId', $genreId);
$stmt->execute();

首先,我沒有將 $stmt 變量傳遞給 filterDataQuery。 我將它傳遞給 bindParams。 bindParams function 是在 filterDataQuery 完成並添加了 order by 和 limit 的字符串之后調用的。

我真的要感謝你,Piemol,你試圖幫助我。

在我大學的一位教授建議我這樣做后,我檢查了 Maria DB 日志,我在那里發現了問題

在同一個 controller 中,我調用了兩個 DAO 方法,一個接一個,一個帶來數據,第二個進行計數。

  $responseMessage = json_encode(AdminDAO::getInstance()->getFilteredSongsList($message));
  $count = AdminDAO::getInstance()->getFilteredSongsListItemsCount($message); // this one was the problem

問題不在於獲取數據的那個,而是我發布的那個。 問題在於進行計數的人。 我沒有在那里添加連接:|。 在那里沒有任何跡象表明錯誤來自什么方法,所以我專注於錯誤的方法(日志中顯示的那個)。 如果我像在 Java 中那樣使用記錄器,就不會發生這樣的事情。

以下是來自 MariaDB 日志文件的查詢: https://www.heypasteit.com/clip/0IUPWG第一個是失敗的,第二個是有效的。

我非常想念 Java 中的 log4j。

感謝所有試圖幫助我的人。

對於那些有這種奇怪問題的人,檢查日志,放置回聲,不要專注於你在 AJAX 響應日志中看到的第一件事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM