udclist - PHP Mysql PDO número de variables vinculadas no coincide con el número de tokens
uncaught pdoexception sqlstate hy093]: invalid parameter number parameter was not define (2)
Colonias faltantes
:blabelimage_rec, **:**asound_rec, **:**bsound_rec, :featured_rec, :format_rec
Hola, he mirado por aquí, pero parece que tampoco puedo encontrar una respuesta a mi problema.
Esta es la primera vez que uso PDO y soy completamente novato.
Tengo una gran cantidad de datos divididos en 2 tablas y quiero fusionarlos en uno, hay otras formas de hacerlo, pero sin entrar en las complicadas razones por las cuales, intento hacerlo de esta manera ...
Genero un conjunto de registros de la tabla de la que quiero copiar datos
construir mi declaración
ejecutarlo en un bucle
pero me sale el siguiente error
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
He revisado y comprobado por tres veces que tengo la misma cantidad de variables, así que ¿por qué "tokens no coinciden? No sé", como dije, soy muy nuevo en esto, así que probablemente me esté perdiendo algo que los profesionales considerarían obvio.
Probablemente valga la pena mencionar que no estoy agregando a cada columna de la tabla, hay otras columnas, pero las dejé fuera de la declaración de preparación ... Aquí está mi código:
//$dbh = new PDO($hostname_Seriously, $DB_USER, $DB_PASSWORD); $dbh = new PDO(''mysql:host=localhost;dbname=seriouslysoulful_summers'', $username_Seriously, $password_Seriously); $stmt = $dbh->prepare("INSERT INTO records_rec (oldid_rec, firstname_rec, artist_rec, aside_rec, bside_rec, label_rec, condition_rec, genere_rec, price_rec, collection_rec, active_rec, info_rec, notes_rec, order_rec, alabelimage_rec, blabelimage_rec, asound_rec, bsound_rec, featured_rec, format_rec) VALUES (:oldid_rec, :firstname_rec, :artist_rec, :aside_rec, :bside_rec, :label_rec, :condition_rec, :genere_rec, :price_rec, :collection_rec, :active_rec, :info_rec, :notes_rec, :order_rec, :alabelimage_rec, :blabelimage_rec, asound_rec, bsound_rec, :featured_rec, :format_rec)"); $stmt->bindParam('':oldid_rec'', $id); $stmt->bindParam('':firstname_rec'', $firstname); $stmt->bindParam('':artist_rec'', $artist); $stmt->bindParam('':aside_rec'',$aside); $stmt->bindParam('':bside_rec'',$bside); $stmt->bindParam('':label_rec'',$label); $stmt->bindParam('':condition_rec'',$condition); $stmt->bindParam('':genere_rec'',$genere); $stmt->bindParam('':price_rec'',$price); $stmt->bindParam('':collection_rec'',$collection); $stmt->bindParam('':active_rec'',$active); $stmt->bindParam('':info_rec'',$info); $stmt->bindParam('':notes_rec'',$notes); $stmt->bindParam('':order_rec'',$order); $stmt->bindParam('':alabelimage_rec'',$alabel); $stmt->bindParam('':blabelimage_rec'',$blabel); $stmt->bindParam('':asound_rec'',$asound); $stmt->bindParam('':bsound_rec'',$bsound); $stmt->bindParam('':featured_rec'',$featured); $stmt->bindParam('':format_rec'',$format); $reccount = 0; //do{ $id = $row_rs_original[''id_prod'']; $firstname = mysql_real_escape_string($row_rs_original[''firstname_prod'']); $artist = mysql_real_escape_string($row_rs_original[''artist_prod'']); $aside = mysql_real_escape_string($row_rs_original[''a_side_prod'']); $bside = mysql_real_escape_string($row_rs_original[''b_side_prod'']); $label = mysql_real_escape_string($row_rs_original[''label_prod'']); $condition = mysql_real_escape_string($row_rs_original[''condition_prod'']); $genere = $row_rs_original[''genre_prod'']; $price = $row_rs_original[''price_prod'']; $collection = mysql_real_escape_string($row_rs_original[''collection_prod'']); $active = $row_rs_original[''active_prod'']; $info = mysql_real_escape_string($row_rs_original[''info_prod'']); $notes = mysql_real_escape_string($row_rs_original[''notes_prod'']); $order = $row_rs_original[''order_prod'']; $alabel = mysql_real_escape_string($row_rs_original[''labelimage_A_prod'']); $blabel = mysql_real_escape_string($row_rs_original[''labelimage_B_prod'']); $asound = mysql_real_escape_string($row_rs_original[''soundfile_A_prod'']); $bsound = mysql_real_escape_string($row_rs_original[''soundfile_B_prod'']); $featured = $row_rs_original[''featured_prod'']; $format = $row_rs_original[''format_prod'']; $stmt->execute(); $reccount = $reccount +1; //} while ($row_rs_original = mysql_fetch_assoc($rs_original)); echo($reccount." - records added...");
Parece que Mark Baker ya respondió tu pregunta, pero quería agregar un par de consejos que me han ayudado mucho.
PDO no necesita mysql_escape_string
Siempre que todo lo que entra en su consulta y que trata con la entrada del usuario esté usando una declaración preparada (como lo está haciendo arriba), no necesita escapar de la entrada con mysql_real_escape_string
[1].
// Don''t worry about SQL injection since all of the user
// defined inputs are being escaped by the PDO package
$sql = "INSERT INTO "
. "`users` "
. "SET "
. "`name` = :name";
$query = $pdo->prepare($sql);
$query->bindParam('':name'', $name);
$query->execute();
Pero tenga en cuenta que la inyección SQL aún es posible si no está vinculando la entrada del usuario:
// SQL injection can totally happen here
$sql = "INSERT INTO "
. "`users` "
. "SET "
. "`name` = $name";
$query = $pdo->prepare($sql);
$query->execute();
[1] http://www.php.net/manual/en/pdo.prepared-statements.php
Intenta hacer tu SQL tan corto como sea posible
Para declaraciones SQL simples, cuanto más corta sea, más fácil será mantenerla y menos probable será que cometa errores. Puede usar una sintaxis INSERT alternativa [2]:
INSERT INTO
`users`
SET
`name` = ''Steve'';
es equivalente a:
INSERT INTO
`users`
(
`name`
)
VALUES
(
''Steve''
);
Eso significa que para declaraciones grandes como la suya, puede efectivamente la mitad de su tamaño porque no necesita repetir todos los nombres de columna:
$sql = "INSERT INTO "
. "`records_rec` "
. "SET "
. "`oldid_rec` = :oldid_rec, "
. "`firstname_rec` = :firstname_rec, "
. "`artist_rec` = :artist_rec, "
. "`aside_rec` = :aside_rec, "
. "`bside_rec` = :bside_rec, "
. "`label_rec` = :label_rec, "
. "`condition_rec` = :condition_rec, "
. "`genere_rec` = :genere_rec, "
. "`price_rec` = :price_rec, "
. "`collection_rec` = :collection_rec, "
. "`active_rec` = :active_rec, "
. "`info_rec` = :info_rec, "
. "`notes_rec` = :notes_rec, "
. "`order_rec` = :order_rec, "
. "`alabelimage_rec` = :alabelimage_rec, "
. "`blabelimage_rec` = :blabelimage_rec, "
. "`asound_rec` = :asound_rec, "
. "`bsound_rec` = :bsound_rec, "
. "`featured_rec` = :featured_rec, "
. "`format_rec` = :format_rec";
$dbh = new PDO(<info goes here>);
$stmt = $dbh->prepare($sql);
// Bind your params here...
[2] http://dev.mysql.com/doc/refman/5.5/en/insert.html
Haz tus declaraciones SQL de varias líneas y bastante
Empecé a formatear mis sentencias de SQL para que tuvieran múltiples líneas (como la anterior) y desde que tuve menos errores de este tipo. Ocupa mucho espacio, pero creo que al final vale la pena. Al hacer que todo se alinee, hace que los errores sobresalgan como un pulgar dolorido.
Feliz codificación!