24

I'm getting this annoying error and although I have an idea of why I'm getting it, I can't for the life of me find a solution to it.

if ($limit) {
   $sth->bindValue(':page', $page - 1, PDO::PARAM_INT);
   $sth->bindValue(':entries_per_page', $page * $entries_per_page, PDO::PARAM_INT);
}

$sth->execute($criteria);

Query contains placeholders (:placeholder). But to add those LIMIT placeholders, I need to use the manual method (bindValue) because otherwise the engine will turn them into strings.

I'm not getting the Invalid number of parameters error, so all placeholders have been bound correctly (I assume).

Query:

SELECT `articles`.*, `regional_municipalities`.`name` AS `regional_municipality_name`, 
       `_atc_codes`.`code` AS `atc_code`, `_atc_codes`.`name` AS `substance`
FROM `articles`
LEFT JOIN `_atc_codes`
ON (`_atc_codes`.`id` = `articles`.`atc_code`)
JOIN `regional_municipalities`
ON (`regional_municipalities`.`id` = `articles`.`regional_municipality`)
WHERE TRUE AND `articles`.`strength` = :strength
GROUP BY `articles`.`id`
ORDER BY `articles`.`id`
LIMIT :page, :entries_per_page

All placeholder values reside in $criteria, except for the last two LIMIT, which I manually bind with bindValue().

silkfire
  • 24,585
  • 15
  • 82
  • 105
  • 1
    Try to search in google "PDO binding LIMIT parameters" – Royal Bg Jun 24 '13 at 11:43
  • 1
    1) It would've been nice to include the human readable error message instead of just the cryptic code, 2) Show your actual query so we can see where the error stems from. – deceze Jun 24 '13 at 11:45
  • 1
    @deceze If there was any human readable message in there, I'd: a) probably solved it by now, b) if not, then included it here. This was the full error message, trust me. – silkfire Jun 24 '13 at 11:47
  • 1
    Error: 2031 (CR_PARAMS_NOT_BOUND)Message: No data supplied for parameters in prepared statement FROM Documentation http://dev.mysql.com/doc/refman/5.0/en/error-messages-client.html – david strachan Jun 24 '13 at 11:50
  • @davidstrachan Do you know why my PHP version does not return that "human readable error message"? – silkfire Jun 24 '13 at 11:52
  • 1
    Sure you're binding `:strength` as well? Sure `$limit` is truthy? – deceze Jun 24 '13 at 11:54
  • @deceze Yeah, `$criteria` only contains one value: `'strength' => string '1g' (length=2)` – silkfire Jun 24 '13 at 11:56

7 Answers7

30

This same error 2031 can be issued when one bind two values with the same parameter name, like in:

  • $sth->bindValue(':colour', 'blue');
  • $sth->bindValue(':colour', 'red');

..so, beware.

Mi-Creativity
  • 9,554
  • 10
  • 38
  • 47
Nowdeen
  • 1,401
  • 14
  • 20
29

You cannot use ->bind* and ->execute($params). Use either or; if you pass parameters to execute(), those will make PDO forget the parameters already bound via ->bind*.

deceze
  • 510,633
  • 85
  • 743
  • 889
20

This exception also appears if you try to run a query with placeholders instead of preparing a statment such as

$stmt = $db->query('SELECT * FROM tbl WHERE ID > ?');

instead of

$stmt = $db->prepare('SELECT * FROM tbl WHERE ID > ?');
AbcAeffchen
  • 14,400
  • 15
  • 47
  • 66
3

From the manual:

public bool PDOStatement::execute ([ array $input_parameters ] )

Execute the prepared statement. If the prepared statement included parameter markers, you must either:

  • call PDOStatement::bindParam() to bind PHP variables to the parameter markers: bound variables pass their value as input and receive the output value, if any, of their associated parameter markers

  • or pass an array of input-only parameter values

You need to pick a method. You cannot mix both.

Álvaro González
  • 142,137
  • 41
  • 261
  • 360
2

It's not exactly an answer, but this error also happens if you try to use a word with a hyphen as placeholders, for example:

$sth->bindValue(':page-1', $page1);

So better use

$sth->bindValue(':page_1', $page1);

1

The exception also happens (at least in MySQL/PDO) when your SQL tries to UPDATE an AUTO_INCREMENT field.

1

This happens if you have mismatching parameters. For example:

$q = $db->prepare("select :a, :b");
$q->execute([":a"=>"a"]);
Charlie
  • 8,530
  • 2
  • 55
  • 53