PDO说我缺少令牌,但我不是 - 这有什么不对

时间:2014-06-12 20:59:37

标签: php pdo

所以我设法吐出(通过var_dump)以下内容:

// This is my whole select statement
string 'SELECT * FROM logs AS LOG WHERE ( LOG.DATE BETWEEN :startMonth AND :endMonth ) AND LOG.VALUE LIKE :filter ' (length=106)

// This is the database object (note the params)
object(Micro\Database)[1667]
  protected 'query' => string 'SELECT * FROM logs AS LOG WHERE ( LOG.DATE BETWEEN :startMonth AND :endMonth ) ' (length=79)
  protected 'params' => 
    array
      ':startMonth' => 
        object(DateTime)[1668]
          public 'date' => string '2014-06-01 00:00:00' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      ':endMonth' => 
        object(DateTime)[1671]
          public 'date' => string '2014-06-30 23:59:59' (length=19)
          public 'timezone_type' => int 3
          public 'timezone' => string 'UTC' (length=3)
      ':filter' => string '%"unit_id": 1030006431%' (length=23)

因此,在查询中,我们看到我正在使用:startMonth:endMonth:filter,然后在参数中我们看到我正在设置相同的变量。一切都应该在那里。但显然不是:

'SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens'

呃....没有所有的代币都在那里。我们来看看代码

public static function findByWildCard($unitId=null, $messageType=null, $filter=null, $month) {
    $sqlSelect = 'SELECT * ' .
                    'FROM logs AS LOG '.
                    'WHERE ( LOG.DATE BETWEEN :startMonth AND :endMonth ) ';


    // Connect to lazarus
    $query = self::connectToLazarus();

    // Start of the specified month. Eg. 2013-01-01 00:00:00
    $startMonth = \DateTime::createFromFormat('Y-m-d H:i:s', $month.' 00:00:00');

    // End of the specified month. Eg. 2013-01-31 11:59:59
    $endMonth = clone $startMonth;
    $oneMonth = \DateInterval::createFromDateString('1 month');
    $oneSecond = \DateInterval::createFromDateString('1 second');
    $endMonth->add($oneMonth)->sub($oneSecond);

    // Get the results from the query
    $query->setQuery($sqlSelect)
        ->setParameter('startMonth', $startMonth)
        ->setParameter('endMonth', $endMonth);

    if (!empty($filter)) {
        $sqlSelect .= 'AND LOG.VALUE LIKE :filter ';
        $query->setParameter('filter', '%'.$filter.'%');
    }

    var_dump($query->getResult()); exit;

}

发生了什么事?

2 个答案:

答案 0 :(得分:3)

在将过滤器添加到查询字符串之前,您正在设置查询。

// Get the results from the query
$query->setQuery($sqlSelect)
    ->setParameter('startMonth', $startMonth)
    ->setParameter('endMonth', $endMonth);

if (!empty($filter)) {
    $sqlSelect .= 'AND LOG.VALUE LIKE :filter ';
    $query->setParameter('filter', '%'.$filter.'%');
}

您正在将查询设置为$ sqlSelect,并在设置查询后aftwards附加过滤器部分,但从不再将查询设置为新值。

答案 1 :(得分:0)

有三个可能导致此类问题的问题

  1. 一个错字。大多数情况下,您只需拼错一些变量或占位符名称。
  2. 令牌数确实与变量数不匹配。重述它们。
  3. 在查询中的多个位置使用具有相同名称的占位符时,非常罕见。要解决这个问题,只需打开仿真模式。