2012-06-10 4 views
20
// BUILD VALUES 
$count = count($matches); 
for($i = 0; $i < $count; ++$i) { 
    $values[] = '(?)'; 
} 
// INSERT INTO DATABASE 
$q = $this -> dbc -> prepare("INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash = hash"); 
$q -> execute($matches); 

Il codice precedente non riesce con il seguente erroreSQLSTATE [HY093]: numero di parametro non valido: parametro non è stato definito

SQLSTATE [HY093]: numero di parametro non valido: parametro non è stato definito

Sebbene quando viene chiamato count($matches) == count($values) appena prima dell'esecuzione?

Cosa sta succedendo qui?

+4

Hai provato a passare array_values ​​($ corrisponde)? –

+0

Perché "ON DUPLICATE KEY UPDATE hash = hash'? Può anche fare "INSERIRE IGNORA ...". Intendevi fare 'UPDATE hash = VALUES (hash)'? – eggyal

+0

La matrice '$ values' conteneva già qualcosa prima del ciclo? Inoltre, perché non preparare un singolo 'INSERT INTO hash (hash) VALUES (?)' Ed eseguirlo più volte? – eggyal

risposta

36

Questo errore si riceve:

SQLSTATE [HY093]: numero di parametro non valido: il parametro non è stato definito

è perché il numero di elementi in $values & $matches non è il lo stesso o $matches contiene più di 1 elemento.

Se $matches contiene più di 1 elemento, che l'inserto sarà sicuro, perché c'è nome solo 1 colonna di riferimento nella query (hash)

Se $values & $matches non contengono lo stesso numero di elementi allora la anche l'inserimento fallirà, a causa della query che si aspetta x parametri, ma sta ricevendo y dati $matches.

Credo che sarà anche necessario assicurarsi che l'hash della colonna abbia anche un indice univoco.

provare il codice here:

<?php 

/*** mysql hostname ***/ 
$hostname = 'localhost'; 

/*** mysql username ***/ 
$username = 'root'; 

/*** mysql password ***/ 
$password = ''; 

try { 
    $dbh = new PDO("mysql:host=$hostname;dbname=test", $username, $password); 
    /*** echo a message saying we have connected ***/ 
    echo 'Connected to database'; 
    } 
catch(PDOException $e) 
    { 
    echo $e->getMessage(); 
    } 


$matches = array('1'); 
$count = count($matches); 
for($i = 0; $i < $count; ++$i) { 
    $values[] = '?'; 
} 

// INSERT INTO DATABASE 
$sql = "INSERT INTO hashes (hash) VALUES (" . implode(', ', $values) . ") ON DUPLICATE KEY UPDATE hash='hash'"; 
$stmt = $dbh->prepare($sql); 
$data = $stmt->execute($matches); 

//Error reporting if something went wrong... 
var_dump($dbh->errorInfo()); 

?> 

Sarà necessario adattarlo un po '.

struttura tabella che ho usato è here:

CREATE TABLE IF NOT EXISTS `hashes` (
    `hashid` int(11) NOT NULL AUTO_INCREMENT, 
    `hash` varchar(250) NOT NULL, 
    PRIMARY KEY (`hashid`), 
    UNIQUE KEY `hash1` (`hash`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; 

codice è stato eseguito sul mio server XAMPP che sta usando PHP 5.3.8 e MySQL 5.5.16.

Spero che questo aiuti.

+0

Grazie per averlo risolto! – Griff

+0

no preoccupazioni, qui per aiutare e imparare – Haroon

+2

Ottima risposta, ho appena eseguito in questo, perché ho definito due colonne con lo stesso identificatore - ': esempio', che dovrebbe anche essere un punto da controllare! – Darren

1

SQLSTATE [HY093]: numero di parametro non valido: parametro non era definito

Purtroppo questo errore non è descrittivo per una serie di diversi problemi legati alla stessa questione - un errore di vincolante. Inoltre, non specifica dove si trova l'errore, quindi il problema non è necessariamente nell'esecuzione, ma l'istruzione sql che era già stata preparata.

Questi sono i possibili errori e le loro soluzioni:

  1. C'è un parametro mancata corrispondenza - il numero di campi non corrisponde ai parametri che sono stati legati. Fai attenzione agli array negli array.Per ricontrollare, utilizzare var_dump ($ var). "print_r" non indica necessariamente se l'indice in un array è un altro array (se l'array ha un valore in esso), mentre lo var_dump lo farà.

  2. Si è tentato di eseguire il bind utilizzando lo stesso valore di bind, ad esempio: ": hash" e ": hash". Ogni indice deve essere unico, anche se logicamente ha senso utilizzare lo stesso per due parti diverse, anche se è lo stesso valore. (è simile a una costante ma più simile a un segnaposto)

  3. Se si sta vincolando più di un valore in un'istruzione (come spesso accade con un "INSERT"), è necessario associareParam e quindi bindValue a i parametri. Il processo qui è di associare i parametri ai campi e quindi associare i valori ai parametri.

    // Code snippet 
    $column_names = array(); 
    $stmt->bindParam(':'.$i, $column_names[$i], $param_type); 
    $stmt->bindValue(':'.$i, $values[$i], $param_type); 
    $i++; 
    //..... 
    
  4. Quando si associa valori a COLUMN_NAMES o nomi_tabelle è possibile utilizzare `` ma non è necessario, ma assicuratevi di essere coerenti.

  5. Qualsiasi valore in virgolette singole viene sempre considerato come una stringa e non verrà letto come nome di colonna/tabella o segnaposto da associare.

+0

Grazie per aver ragione # 2, è rimasto sbalordito fino a Ho trovato questo qui. – swa66