2011-05-20 14 views
12
$statement = $db->prepare('SELECT blah FROM blah_table WHERE blahID IN (:a, :b, :c)'); 

¿Qué ocurre si se desconoce el número de parámetros hasta el tiempo de ejecución? Lo único que se me ocurre hacer es crear un tipo hacky de cadena sql para crear tantos marcadores de posición de parámetros como lo necesite.PDO vinculan un número desconocido de parámetros?

+0

Realmente, ¿marcar esto como un duplicado de una pregunta más nueva? – Kickstart

+0

@Kickstart ¿Por qué no? Si la otra pregunta es buena y brinde respuestas útiles. – Eiko

+0

@Eiko: ¿por qué marcar como duplicado varios años después de que la misma persona respondió el duplicado y dio esencialmente la misma respuesta que una existente aquí? – Kickstart

Respuesta

4

Usted puede construir el "IN (...)" cadena de forma dinámica:

$in_string = '('; 
foreach ($array_of_parameters as $parameter) { 
    $in_string .= ':' . chr($i + 97) . ','; // Get the ASCII character 
} 
$in_string = substr($in_string, 0, -1) . ')'; 

$statement = $db->prepare("SELECT blah FROM blah_table WHERE blahID IN ($in_string)"); 
+8

¿Por qué se tomaría la molestia de usar marcadores de posición con nombre? Usando un ? funciona igual de bien sin el trabajo extra? – Paystey

11

No muy hacky, los bucles son parte del lenguaje para el bucle de una cantidad variable de veces.


$values = array('val1', 'val2'); 
$sql = 'SELECT * FROM Table Where column IN('; 
$params = array(); 
foreach ($values as $val) 
{ 
    $params[] = '?'; 
    $binds[] = $val; 
} 
$prep = $db->prepare($sql . join(', ', $params) . ')'); 
$i = 0; 
foreach($binds as $bind){ 
    $prep->bindValue(++$i, $bind); 
} 
$prep->execute(); 

bucle sobre cada valor que necesita para unirse, crear una matriz de objetos que se recorre después añadiendo el SQL vinculante.

2

Sólo otro camino más corto de hacerlo.

$values = array(1, 2, 3, 4); 
$sql = "SELECT * 
      FROM table 
     WHERE column IN (" . join(',', array_map(function() { return '?'; }, $values)) . ")"; 
$db->prepare($sql); 
$db->execute($values); 
+0

Será muy apreciado si proporciona alguna explicación a su código. –

+0

@IllegalArgument ¿qué parte le gustaría explicar? [join] (http://php.net/manual/en/function.join.php), [matriz_registro] (http://php.net/manual/en/function.array-map.php) –

+1

@IllegalArgument Está utilizando el hecho de que array_map acepta una función de devolución de llamada que se realizará en cada elemento de la matriz. Aunque es un poco exagerado =) ¿Algo como ''?' . str_repeat (',?', count ($ arr) - 1) 'o' rtrim (str_repeat (',', count ($ arr)), ',') 'sería lo suficientemente bueno, ya que solo quieres una pregunta marca para cada elemento de la matriz. – nimmneun

0

Una forma de hacerlo sin un bucle explícito pero dando marcadores específicos en lugar de signos de interrogación.

$values_array = array(1, 3, 5, 7, 11); 
$sql = "SELECT * 
      FROM table 
     WHERE column IN (" . implode(",", array_map(function($in){return ':a'.$in;}, range(1, count($values)))) . ")"; 
$prep = $db->prepare($sql); 
$i = 1; 
foreach($values_array as $key=>$value) 
{ 
    $prep->bindValue(':a'.$i++, $values_array[$key]); 
} 

Esto utiliza gama para generar una matriz de números de 1 al número de elementos de la matriz, a continuación, array_map para cambiar esos números para anteponer ellos con un: y un carácter (en este caso sólo una).

Solo lo hice debido a intentar depurar algo que usaba signos de interrogación y estaba fallando. El problema resultó estar en otra parte (debido a un bucle en la matriz para enlazar los valores y tener problemas con bind usando la referencia a la variable, que se modificó en cada iteración de la matriz, por lo tanto, aterrizó teniendo el mismo valor en cada uno obligar a posiciones), pero pensé que esto podría ser útil para alguien.

+0

Espero que no ayude a nadie. Como usar marcadores de posición con nombre en este caso es solo un [...]. Si bien para evitar un ciclo explícito, solo tiene que evitarlo, como se muestra en la otra respuesta. –

+0

En los casos de noddy tal vez sea cierto, pero si tiene (por ejemplo) un par de consultas unificadas que tienen los mismos parámetros que se pasan, puede recorrer los parms una vez para vincularlos a marcadores específicos en lugar de solo en el orden de los signos de interrogación son útiles. – Kickstart

Cuestiones relacionadas