2013-06-24 14 views
15

Ricevo questo fastidioso errore e anche se ho un'idea del motivo per cui lo sto ottenendo, non posso per la vita di me trovare una soluzione ad esso .Errore PDO: SQLSTATE [HY000]: errore generale: 2031

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 query contiene segnaposto (:placeholder). Ma per aggiungere quei LIMITI segnaposto, ho bisogno di usare il metodo manuale (bindValue) perché altrimenti il ​​motore li trasformerà in stringhe.

Non riesco ad ottenere l'errore di numero di parametri errato, quindi tutti i segnaposto sono stati correttamente associati (presumo).

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 

Tutti i valori segnaposto risiedono nei criteri di $, tranne che per gli ultimi due LIMIT, che mi legano manualmente con bindValue().

+1

Prova a cercare su google "DOP parametri limite vincolante" –

+0

1) Sarebbe stato bello per includere il messaggio di errore leggibile invece di solo il codice criptico, 2) Mostrare la query in modo reale possiamo vedere da dove proviene l'errore. – deceze

+0

@deceze Se ci fosse qualche messaggio umano leggibile lì, io: a) probabilmente l'ho risolto ora, b) se no, quindi incluso qui. Questo era il messaggio di errore completo, fidati di me. – silkfire

risposta

17

Non è possibile utilizzare ->bind*e->execute($params). Utilizzare uno o; se si passano i parametri a execute(), questi faranno in modo che PDO dimentichi i parametri già associati tramite ->bind*.

3

Da 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

è necessario scegliere un metodo. Non puoi mescolare entrambi.

+0

Non posso usare' bindParam'/'bindValue' per gli altri valori ... sospiro. – silkfire

+0

@silkfire Si prega di consultare http://stackoverflow.com/questions/10014147/limit-keyword-on-mysql-with-prepared-statement-maybe-still-a-bug/10014200#10014200 per altre idee. –

+0

'PDO :: ATTR_EMULATE_PREPARES, true)' - non dovrebbe ** abilitare ** preparati emulati? Penso che sia il contrario, molto fuorviante. – silkfire

13

Questo stesso errore 2031 può essere rilasciato quando si legano due valori con lo stesso nome del parametro, come in:

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

..quindi, attenzione.

+0

Questa risposta mi ha salvato la giornata! – JWizard

2

Questa eccezione appare anche se si tenta di eseguire una query con i segnaposto invece di preparare uno statment come

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

invece di

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

L'eccezione avviene anche (almeno in MySQL/PDO) quando l'SQL tenta di AGGIORNARE un campo AUTO_INCREMENT.

2

Non è esattamente una risposta, ma questo errore si verifica anche se si tenta di utilizzare una parola con un trattino come segnaposto, per esempio:

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

Quindi meglio usare

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

0

Questo succede se si hanno parametri di mancata corrispondenza.Per esempio:

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