web-dev-qa-db-fra.com

Erreur PDO: SQLSTATE [HY000]: Erreur générale: 2031

Je reçois cette erreur agaçante et bien que j'aie une idée de la raison pour laquelle je l'obtiens, je ne peux pas pour la vie me trouver une solution.

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);

La requête contient des espaces réservés (:placeholder). Mais pour ajouter ces espaces réservés LIMIT, je dois utiliser la méthode manuelle (bindValue), sinon le moteur les transformera en chaînes.

Je ne reçois pas l'erreur Nombre de paramètres non valide. Tous les espaces réservés ont donc été liés correctement (je suppose).

Question:

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

Toutes les valeurs d'espace réservé résident dans les critères $, à l'exception des deux derniers LIMIT, que je lie manuellement avec bindValue().

19
silkfire

Vous ne pouvez pas utiliser ->bind* et ->execute($params). Utilisez soit ou si vous passez des paramètres à execute(), PDO oubliera les paramètres déjà liés via ->bind*.

19
deceze

Cette exception apparaît également si vous essayez d'exécuter une requête avec des espaces réservés au lieu de préparer une déclaration telle que

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

au lieu de 

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

De le manuel :

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

Exécutez l'instruction préparée. Si l'instruction préparée inclut des marqueurs de paramètre, vous devez soit :

  • appelez PDOStatement :: bindParam () pour lier les variables PHP aux marqueurs de paramètre: les variables liées transmettent leur valeur en tant qu'entrée et reçoivent la valeur de sortie, le cas échéant, de leurs marqueurs de paramètre associés

  • ou passez un tableau de valeurs de paramètres d'entrée seulement

Vous devez choisir une méthode. Vous ne pouvez pas mélanger les deux.

3
Álvaro González

Cela se produit si les paramètres ne correspondent pas. Par exemple:

$q = $db->prepare("select :a, :b");
$q->execute([":a"=>"a"]);
0
Charlie