0

我正在使用这样的SELECT查询:

SELECT knowledge.*, 
       sortflagitems.* 
FROM   knowledge, 
       sortflagitems 
WHERE  sortflagitems.flagid = :FlagID 
       AND knowledge.id = sortflagitems.kid 
       AND sortflagitems.cid = :CID 
       AND knowledge.archived = :Nothing 
       AND sortflagitems.flagdate <= :Now 
ORDER  BY sortflagitems.sortorder 

这会产生这个错误:

 Invalid parameter number: number of bound variables does not match number of tokens

但是,如果我将SELECT查询更改为:

SELECT knowledge.*, 
       sortflagitems.* 
FROM   knowledge, 
       sortflagitems 
WHERE  sortflagitems.flagid = :FlagID 
       AND knowledge.id = sortflagitems.kid 
       AND sortflagitems.cid = :CID 
       AND knowledge.archived = :Nothing 
       AND sortflagitems.flagdate = :Now 
ORDER  BY sortflagitems.sortorder 

这不会产生任何错误

请注意,此行SortFlagItems.FlagDate=:Now已从SortFlagItems.FlagDate<=:Now

我唯一的理论是,由于某种原因,当您选择多个表时,您不能使用<=运算符(请注意,使用<运算符会产生相同的错误)?想不出别的了。。


这是完整的 PHP 代码:

$DBParams = array('FlagID'=>$_GET['flag'], 'CID'=>$row['CatID'], 'Nothing'=>0, 'Now'=>strtotime('now'));
$results = $Db->rquery('
                    SELECT Knowledge.*, SortFlagItems.*
            FROM Knowledge, SortFlagItems
            WHERE SortFlagItems.FlagID=:FlagID
            AND Knowledge.id = SortFlagItems.KID
            AND SortFlagItems.CID=:CID
            AND Knowledge.Archived=:Nothing
            AND SortFlagItems.FlagDate<=:Now
            ORDER BY SortFlagItems.SortOrder', $DBParams);

这是rquery功能:

function rquery($query, $params = NULL) {
    $this->_query = filter_var($query, FILTER_SANITIZE_STRING);
    $stmt = $this->_prepareQuery();
    $stmt->execute($params);

    $results = $this->_dynamicBindResults($stmt);

    return $results;
}

和构造函数:

public function __construct($host, $username, $password, $db) {
    $this->_mysql = new PDO("mysql:host=$host;dbname=$db", $username, $password);
    $this->_mysql->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
4

1 回答 1

1

我的解决方案是从您的方法中删除 filter_var :

function rquery($query, $params = NULL) {
    $this->_query = $query;
    $stmt = $this->_prepareQuery();
    $stmt->execute($params);

    $results = $this->_dynamicBindResults($stmt);

    return $results;
}

绑定将为您阻止 sql 注入。
如果需要,您可以filter_var()在内部参数上使用_dynamicBindResults

或者您可以在传递查询之前在每个参数上使用它:

$DBParams = array('FlagID'=>filter_var($_GET['flag'], FILTER_SANITIZE_STRING),...);

这里的连接是一个显式连接:

SELECT Knowledge.*, SortFlagItems.*
FROM Knowledge
INNER JOIN SortFlagItems ON Knowledge.id = SortFlagItems.KID
WHERE SortFlagItems.FlagID=:FlagID
AND SortFlagItems.CID=:CID
AND Knowledge.Archived=:Nothing
AND SortFlagItems.FlagDate<=:Now
ORDER BY SortFlagItems.SortOrder
于 2013-02-28T20:32:58.240 回答