我在这里有一个非常奇怪的问题 - 这是一个小的解决方法,因为PDO无法将num_rows
与MySQL结合使用。
我可以通过phpmyadmin直接将此查询提供给数据库:
SELECT COUNT(*) AS COUNT
FROM ((
(SELECT 'Key' AS tradeOrigin,
CONCAT(skti.tier, ' ', skty.type) AS trade,
CONCAT('Amount: ', t.sourceKeyAmount) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 1
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = 18
JOIN keytiers skti ON t.sourceKeyTierId = skti.keyTierId
JOIN keytypes skty ON t.sourceKeyTypeId = skty.keyTypeId)
UNION ALL
(SELECT 'Mod' AS tradeOrigin,
sm.name AS trade,
CONCAT('Level: ', IF(t.sourceModLevel = 0, 'Unranked', t.sourceModLevel)) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 2
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = 18
JOIN mods sm ON t.sourceModId = sm.modId)) AS derived)
它会返回一行count
,值1
为预期。
但是当它需要通过我的框架时会出错。
执行代码:
if (!empty($sql)) {
try {
echo $sql."<br><pre>";
print_r($dataArray);
echo "</pre>";
$numrows = $dbh->num_rows($sql, $dataArray);
} catch (PDOException $ex) {
// echo $ex;
error($ex);
}
//...
输出:
(SELECT 'Key' AS tradeOrigin,
CONCAT(skti.tier, ' ', skty.type) AS trade,
CONCAT('Amount: ', t.sourceKeyAmount) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 1
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = :modId
JOIN keytiers skti ON t.sourceKeyTierId = skti.keyTierId
JOIN keytypes skty ON t.sourceKeyTypeId = skty.keyTypeId)
UNION ALL
(SELECT 'Mod' AS tradeOrigin,
sm.name AS trade,
CONCAT('Level: ', IF(t.sourceModLevel = 0, 'Unranked', t.sourceModLevel)) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 2
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = :modId
JOIN mods sm ON t.sourceModId = sm.modId)
Array
(
[:modId] => 18
)
这进入(注意:$this->dbh
是PDO
个实例):
/**
* Returns the number of rows that this query has.
*
* @param type $query The input query
* @param type $values The values
* @return type Number of rows
*/
public function num_rows($query, $values) {
$newquery = "SELECT COUNT(*) AS count FROM (({$query}) AS derived)";
echo $newquery;
$statement = $this->query($newquery, $values);
$i = $statement->fetch();
echo "<pre>";
print_r($i);
echo "</pre>";
return $i->count;
}
它回应:
SELECT COUNT(*) AS COUNT
FROM ((
(SELECT 'Key' AS tradeOrigin,
CONCAT(skti.tier, ' ', skty.type) AS trade,
CONCAT('Amount: ', t.sourceKeyAmount) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 1
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = :modId
JOIN keytiers skti ON t.sourceKeyTierId = skti.keyTierId
JOIN keytypes skty ON t.sourceKeyTypeId = skty.keyTypeId)
UNION ALL
(SELECT 'Mod' AS tradeOrigin,
sm.name AS trade,
CONCAT('Level: ', IF(t.sourceModLevel = 0, 'Unranked', t.sourceModLevel)) AS tradeInfo,
'Platinum' AS tradeToOrigin,
t.destinationPlatinum AS tradeTo,
'' AS tradeToInfo,
u.ingame AS seller,
DAYSPASSED(added) AS daysPassed,
DATEDIFF(NOW(), added) AS sortingSince
FROM trades t
JOIN users u ON t.sourceItem = 2
AND t.destinationItem = 1
AND t.userId = u.userId
AND t.sourceModId = :modId
JOIN mods sm ON t.sourceModId = sm.modId)) AS derived)
stdClass Object
(
[count] => 0
)
哪个电话:
/**
* Can be called to create a query. Use either unnamed or named placeholders for the prepared statements.
*
* Example: $dbh->query("INSERT INTO table (data1, data2) VALUES(?, ?)", array($data1, $data2));
*
* @param type $query The input query, including unnamed or named placeholders
* @param type $values The input values. If it's not an array, then it will be an one-element array
* @return type The statement constructed by this query
*/
public function query($query, $values = array()) {
if (!is_array($values)) {
$values = array($values);
}
$statement = $this->dbh->prepare($query);
$statement->setFetchMode(PDO::FETCH_OBJ);
if (is_assoc($values)) {
foreach ($values as $key => $value) {
$statement->bindValue($key, $value);
}
}
else {
$i = 1;
foreach ($values as $value) {
$statement->bindValue($i++, $value);
}
}
$statement->execute();
return $statement;
}
query
方法已被证明在过去有效,而且奇怪的是num_rows
确实可以处理其他任意返回6作为计数的任意查询。
我真的被困在这里并且不知道发生了什么,请帮助我。
更新:
最近有一个设置向我介绍了这个问题:$this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
。
但是我仍然想知道它为什么会导致这个问题,因为我不能只是禁用它,因为我将它用于其他失败的LIMIT
子句(很多关于这个问题的SO帖子)。帖子的示例如下:How to apply bindValue method in LIMIT clause?
答案 0 :(得分:1)
根据评论中的讨论,您现在似乎已经掌握了足够的信息:您的PDO设置阻止您的绑定工作。
你说你正在使用该设置让LIMIT正常工作 - 我猜测绑定到LIMIT。您通常不能这样做,因为绑定仅用于参数值(即在WHERE
子句中),而LIMIT
子句不被视为参数。你能用另一种方式重写绑定的LIMIT
查询吗?
最后,根据评论,确保您使用的任何别名都是小写,而不是保留字。您可以使用这些不区分大小写的,但无论如何都可以使用代码约定!
答案 1 :(得分:1)
$statement->bindValue($key, $value);
您是否尝试使用$statement->bindParam
?
因为结果不同,Sql本身没有问题,但问题出在值或绑定中。