簡體   English   中英

PHP MySQL預准備語句聯接錯誤

[英]PHP MySQL Prepared Statement Join Error

更新:請參見下文; 我刪除了所有抽象並創建了一個簡單的PHP腳本,但仍然遇到相同的錯誤。 有關更多信息,請參見下面的“另一個更新” ...

原始帖子:我有一個通過數據庫抽象層正確構成的查詢。 查詢如下:

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id,  
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = 5c9_dpd_users.cms_usergroup_id 
ORDER BY username asc

如果我生成相同的查詢,但將其作為准備好的語句運行,該語句按如下所示參數化WHERE子句的第二個操作數,則會得到錯誤的結果。 我確信該語句本身是正確的,並且我正在運行MySQLi准備。 語句以正確的順序運行。 准備好的語句查詢如下:

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users LEFT JOIN 
5c9_dpd_usergroups_cms ON 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc

該查詢似乎將參數5c9_dpd_users.cms_usergroup_id值簡單地轉換為“ 5”,因為運行查詢從SELECT子句中檢索正確的列,但對所有結果返回相同的usergroup_name該用戶組名稱與該用戶組名稱與該結果相匹配的用戶組名稱的5c9_dpd_usergroups_cms.id5

我正在動態綁定參數( call_user_func_array() )。 在這種情況下,我告訴它綁定? 參數作為i 我以為是由於某種原因,這可能使它將5c9_dpd_users.cms_usergroup_id轉換為5 ,但是我嘗試了所有其他三種數據類型( sbd ),但沒有成功。

注意:盡管這是它運行連接的第一個實例(它是最近才開發的),但我已經多次使用我的數據庫抽象層了。 重申一下,如果未參數化查詢,但給定一個? ,則查詢會通過PHP和MySQL控制台返回正確的結果? 通過PHP編寫的語句函數,結果不正確,如上所述。

如果有人可以提供幫助,我將不勝感激。 我整夜忙着搜尋有關此事的幫助,但在任何地方都找不到任何類似的實例。 謝謝。

編輯(提供PHP代碼):

$stmt->select_prep(array('users.id', 'users.username', 'users.cms_usergroup_id', 'usergroups_cms.usergroup_name', 'users.email'), array('users'));
$stmt->left_join_prep('usergroups_cms');
$stmt->on_prep('usergroups_cms.id', '=', 'users.cms_usergroup_id', 'i');

$stmt->order($column, $asc_desc);
$stmt->execute_prep();

現在執行查詢,我所要做的就是調用$ stmt-> fetch_prep(),這是一個包裝方法,基本上可以檢索結果集。 該客戶端代碼生成的查詢在上面給出,作為我給出的第二個參數化查詢。

我在$ stmt-> execute_prep()方法中打印了一些調試代碼,並且綁定到查詢的參數正確顯示為:

Array
(
  [0] => i
  [1] => 5c9_dpd_users.cms_usergroup_id
)

這意味着它將一個參數(鍵1)綁定為一個int(鍵0)。 我也嘗試將其綁定為字符串,double和blob,但沒有任何效果。

另一個更新:

我創建了一個測試腳本以完全刪除我的數據庫抽象層,結果是相同的:沒有返回cms用戶組名稱。 這是腳本:

<?php
$mysqli = new mysqli('localhost', 'root', '', 'frame');

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ? 
ORDER BY username asc";

$stmt = $mysqli->prepare($q);
$stmt->bind_param('i', $param);
$param = 'ac9_dpd_users.cms_usergroup_id';
$stmt->execute();

$stmt->bind_result($a, $b, $c, $d, $e);

while ($stmt->fetch()) {
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>";
}

$stmt->close();
unset($mysqli);
?>

輸出:

id: 7 
un: ADD 
id: 1 
cms name: 
email: test@test.com

id: 1 
un: New User 
id: 2 
cms name: 
email: test@test.com

等等

也許我有點挑剔,但我不會以數字開頭的表/字段名稱。 使用字母或將這些怪異的名稱用反引號( ` )引起來。 它應該工作。

編輯(根據您的問題更改)

您編輯過的腳本的某些地方會向我發出警報:

     ...
     ON ac9_dpd_usergroups_cms.id = ? 
     ...
     $stmt->bind_param('i', $param);
     $param = 'ac9_dpd_users.cms_usergroup_id';

如php手冊中所述, mysqli :: prepare將參數接受到where子句中,並且不允許更改查詢的列名。

此外,對字符串進行整數綁定應該在將值插入准備好的查詢之前將值轉換為數字,並且$ params應該轉換為0。

發出sqlstate語句以在執行后立即檢查查詢的內容:

...
$stmt->execute();
$sqlError = $stmt->sqlstate();
if($sqlError != '00000') die($sqlError);
...

可能的解決方案:

<?php
$mysqli = new mysqli('localhost', 'root', '', 'frame');

$q = "SELECT ac9_dpd_users.id, ac9_dpd_users.username, ac9_dpd_users.cms_usergroup_id, 
ac9_dpd_usergroups_cms.usergroup_name, ac9_dpd_users.email 
FROM ac9_dpd_users 
LEFT JOIN ac9_dpd_usergroups_cms 
ON ac9_dpd_usergroups_cms.id = ac9_dpd_users.cms_usergroup_id 
ORDER BY username asc";

$stmt = $mysqli->prepare($q);
$stmt->execute();

$stmt->bind_result($a, $b, $c, $d, $e);

while ($stmt->fetch()) {
    echo "id: $a <br>un: $b <br>id: $c <br>cms name: $d <br>email: $e<br><br>";
}

$stmt->close();
unset($mysqli);
?>

暫無
暫無

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

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