2011-01-07 11 views
14

Durante una inscripción en línea, un cliente puede seleccionar una serie de programas para los que elige inscribirse. Estos programas son enteros de tres dígitos y se almacenan en una matriz.Cómo insertar una matriz en una única declaración preparada de MySQL con PHP y PDO

Por ejemplo:

Quiero inscribirse en programid 155, 165, 175 y 185.

Mi matriz esté configurada tan simple como:

$data = array(); 

$data[] = 155; 

$data[] = 165; 

$data[] = 175; 

$data[] = 185; 

Cuando llega el momento para insertar esta información en la tabla asociada, también incluyo elementos adicionales de la otra parte de la inscripción:

Por ejemplo, si estuviera haciendo un inserto del programa SINGLE declaración temperatura ambiente, se vería de la siguiente manera:

$stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()"); 
$stmt->execute(array($memberid, 155)); 

Me normalmente crear un bucle simple para la matriz por encima de lo que exigiría varias instancias de la instrucción SQL y ejecutar tales como:

for($j = 0; $j < (count($data)-1); $j++) { 
    $stmt = $db->prepare("INSERT INTO table SET memberID=?, programID=?, date_added=NOW()"); 
    $stmt->execute(array($memberid, $data[$j])); 
} 

hago se da cuenta de que el código anterior no es válido ($ data [$ j]) pero está buscando la forma correcta de hacer la llamada.

También me han dicho antes que la construcción de una única declaración SQL dinámica es en general mejor que las llamadas múltiples como la anterior. Mi primer paso sería algo así como:

$sql = array(); 
foreach($data as $row) { 
    $sql[] = '("'.$memberid.'", "'.$row[$j].'", NOW()")'; 
} 
mysql_real_query('INSERT INTO table (memberid, programid) VALUES '.implode(',', $sql)); 

pero con DOP No estoy muy seguro de cómo funciona esto, especialmente con marcadores de posición (?).

¿Alguna sugerencia?

+2

no se corre el preparar más de una vez. Uno está preparado, puede ejecutarlo varias veces con diferentes valores. – Powerlord

Respuesta

25

Se puede construir la consulta mediante programación ...:

$sql = 'INSERT INTO table (memberID, programID) VALUES '; 
$insertQuery = array(); 
$insertData = array(); 
foreach ($data as $row) { 
    $insertQuery[] = '(?, ?)'; 
    $insertData[] = $memberid; 
    $insertData[] = $row; 
} 

if (!empty($insertQuery)) { 
    $sql .= implode(', ', $insertQuery); 
    $stmt = $db->prepare($sql); 
    $stmt->execute($insertData); 
} 
+0

gracias por la sugerencia. Estoy jugando con eso ahora mismo. La implosión está arrojando un error, pero te dejaré saber qué ocurre. – JM4

+0

@ JM4: fue un pequeño error de mi parte. Lo he arreglado arriba ... – ircmaxell

+0

genial. ¡gracias por la ayuda! Pensando en la fecha_agregada en el ejemplo anterior, la creación de un nuevo elemento $ insertdata [] = NOW() no se insertaría correctamente (ya que PDO lo trataría como una entrada varchar y lo trataría literalmente en lugar del formato de fecha mysql).Normalmente, simplemente generaría la consulta: date_added = NOW() pero con los valores anteriores, ¿se puede hacer esto? Me doy cuenta de que simplemente podría ejecutar php date (Y-m-d H: i: s) pero quería ver si NOW() era posible. – JM4

0

Lo que se busca es cómo hacer una inserción masiva, esto es más relacionados con SQL que a sí DOP.

Solo tiene que hacer exactamente lo mismo que con * _query, compile su consulta de inserción masiva y su matriz de param uno al lado del otro.

$placeholder = array(); 
$values = "?, ?, ?, ..."; 
$args = array(); 
foreach ($arrays as $array) { 
    $placeholder[] = $value; 
    $args[] = $array['col1']; 
    $args[] = $array['col2']; 
    $args[] = $array['col3']; 
    ... 
}  
$sql = "INSERT INTO table (col1, col2, ...) VALUES (" 
    . implode('), (', $placeholder) 
    . ")"; 
$stmt = $db->prepare($sql); 
$db->execute($sql, $args); 

Esto es un algoritmo feo pero funcional, creo.

9

2 soluciones

// multiple queries 
$stmt = $pdo->prepare('INSERT INTO table SET memberID=:memberID, programID=:programID, date_added=NOW()'); 
$data = array(155, 165, 175, 185); 
foreach($data as $d) { 
    $stmt->execute(array(':memberID' => $memberid, ':programID' => $d)); 
} 

Y

// one query 
$data = array(155, 165, 175, 185); 
$values = array(); 
foreach($data as $d) { 
    $values[] = sprintf('(%d, %d, NOW())', $d, $memberid); 
} 
$sql = sprintf('INSERT INTO table (memberID, programID, date_added) VALUES %s', implode (', ', $values)); 
$pdo->exec($sql); 
+0

gracias por su publicación, aunque, ¿no es la primera respuesta anterior la realización de múltiples consultas y el gravamen de la base de datos más que el último? (la mayoría me han dicho que no lo use como tal). Voy a probar este último ya que parece que probablemente se ajuste mejor a mis necesidades. De nota: no tengo ningún problema para hacer varias consultas, solo me han dicho que es 'más lento' (con un máximo de 8 registros, un segundo no significa nada para mí). – JM4

+0

Las consultas múltiples son más lentas unos diez milisegundos, pero son más fáciles de leer y de depurar. –

Cuestiones relacionadas