2012-08-13 36 views
5

Tengo que seleccionar algunas filas de la base de datos usando el operador IN. Quiero hacerlo usando una declaración preparada. Este es mi código:Declaraciones preparadas MySQLi con el operador IN

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$in_statement = '"' . implode('", "', $lastnames) . '"'; //"braun", "piorkowski", "mason", "nash" 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN (?)'); 
$data_res->bind_param('s', $in_statement); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 
?> 

Pero no devuelve nada aunque todos los datos existen en la base de datos.

Y uno más: si paso $in_statement directamente para consultarlo y ejecutarlo, los datos serán devueltos. Entonces el problema aparece en la preparación.

Estaba buscando la pregunta en Google pero no fue exitosa. ¿Qué pasa con mi código?
¡Gracias por la ayuda!

+3

No puede usar un solo parámetro para su cláusula IN. Tiene que ser: 'WHERE lastname IN (?,?,?,?)' – andrewsi

+1

Bien, muchas gracias!) Parece un poco engorroso. – kpotehin

Respuesta

4

Recientemente he encontrado la solución para mi pregunta. Tal vez no sea la mejor manera de hacerlo, ¡pero funciona bien! Demuestre que estoy equivocado :)

<?php 
$lastnames = array('braun', 'piorkowski', 'mason', 'nash'); 
$arParams = array(); 

foreach($lastnames as $key => $value) //recreate an array with parameters explicitly passing every parameter by reference 
    $arParams[] = &$lastnames[$key]; 

$count_params = count($arParams); 

$int = str_repeat('i',$count_params); //add type for each variable (i,d,s,b); you can also determine type of the variable automatically (is_int, is_float, is_string) in loop, but i don't need it 
array_unshift($arParams,$int); 

$q = array_fill(0,$count_params,'?'); //form string of question marks for statement 
$params = implode(',',$q); 

$data_res = $_DB->prepare('SELECT `id`, `name`, `age` FROM `users` WHERE `lastname` IN ('.$params.')'); 
call_user_func_array(array($data_res, 'bind_param'), $arParams); 
$data_res->execute(); 
$result = $data_res->get_result(); 
while ($data = $result->fetch_array(MYSQLI_ASSOC)) { 
    ... 
} 

$result->free(); 
$data_res->close(); 
?> 
2

Declaraciones preparadas tienen el propósito de evitar exactamente lo que estás tratando de hacer que hacer :)

Para conseguir que esto funcione tiene que aplicar este paso:

$escaped_lastnames = join(',', array_map(array($_DB, 'real_escape_string'), $lastnames)); 

Al trazar la cadena adecuada función de escape para su base de datos en cada artículo de $lastnames. Cuando termine, inserte este valor directamente en la consulta, es decir, sin usar parámetros vinculados.

+0

Gracias, Jack, pero encontré la manera de hacer esta consulta a través de una declaración preparada. Estoy usando call_user_func_array (array ($ data_res, 'bind_param'), $ arParams); en cambio regular bind_param. $ arParams contiene tipos de variables y estas variables exactamente) – kpotehin

+0

Acabo de publicar mi código como respuesta) – kpotehin

+2

@kpotehin seguro, si realmente debes (ab) usar declaraciones preparadas para esto, puedes por supuesto :) personalmente no veo el beneficio, a menos que tenga que ejecutarse varias veces dentro de una ejecución de php –

Cuestiones relacionadas