2011-12-02 33 views
7

Estoy tratando de usar la respuesta de staticsan en this question para declaraciones preparadas. permite echar este ejemplo:¿Cómo insertar múltiples filas en una base de datos mysql a la vez con declaraciones preparadas?

$stmt = $mysqli->prepare("INSERT INTO something (userid, time, title) VALUES (?, ?, ?)"); 
$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

En respuesta staticsan's implosión de la matriz es la adición de todos los valores en la declaración de MySQL por lo que al final podemos insertar varios datos en la base de datos con una sola declaración. ¿Cómo se haría esto en mi ejemplo?

+0

Su ejemplo tiene un número fijo de parámetros, por lo que es ya resuelto ¿Puedes elaborar tu problema un poco más? ¿Qué has intentado hasta ahora? Básicamente debería funcionar igual pero agregar más parámetros, p. en un bucle 'foreach'. – hakre

+0

Puede formar una declaración preparada usando el código mencionado aquí, http://stackoverflow.com/questions/1176352/pdo-prepared-inserts-multiple-rows-in-single-query –

Respuesta

5

Esto es completamente válido:

$stmt = $mysqli->prepare("INSERT INTO something (userid, time, title) VALUES (?, ?, ?)"); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

$stmt->bind_param('iis', $userid, time(), $title); 
$stmt->execute(); 

Puede foreach sobre su matriz de valores de insertar y se unen y ejecutar cada vez. No será tan rápido como la inserción masiva en el ejemplo que vinculó, pero será más seguro.

+1

Gracias, eso funciona. Pero la ejecución() se ejecutará para cada elemento de la matriz, por lo que cada fila se insertará en la base de datos por separado y no todos al mismo tiempo. ¿Estoy en lo cierto? Esperaba ver una solución donde bind_param primero todos los valores y, al final, ejecutarlo una vez. – phpheini

+0

Sí, eso es correcto, pero la principal ventaja es el aumento de velocidad proporcionado por la declaración preparada: preparar la declaración una vez y ejecutarla varias veces es mucho más rápido que prepararla cada vez. –

+0

Sin embargo, esto es mucho más lento que una vieja consulta estática 'INSERT', ¿o no? Quiero decir, la ejecución de consultas en un bucle crea un retraso de ~ 2 ms entre cada consulta. Con arreglos grandes, esto llevaría una eternidad, ¿no? – NoobishPro

-2

La consulta se parece a esto:

INSERT INTO people (name, age) 
    VALUES 
    ('Helen', 24), 
    ('Katrina', 21), 
    ('Samia', 22), 
    ('Hui Ling', 25), 
    ('Yumie', 29) 
+4

Sí, pero no para las declaraciones preparadas. La pregunta es, ¿tengo que escribir '$ mysqli-> prepare (" INSERT INTO (userID, time, title) VALUES (?,?,?), (?,?), (?? ,?) ");' y luego 'bind_param ('iisiisiis', $ userid [0], time(), $ title, $ userid [0], time(), $ title [0], $ userid [1], time(), $ title [1], $ userid [2], time(), $ title [2]); ' – phpheini

2

Usted puede construir declaración preparada utilizando el código como se ha mencionado aquí,

PDO Prepared Inserts multiple rows in single query

lógica de PHP será algo así como,

/** 
* Insert With Ignore duplicates in Mysql DB. 
* 
* @param string $date Date. 
*/ 
public static function insertWithIgnore($em, $container, $tableName, $fields, $rows) 
{ 
    $query = "INSERT IGNORE INTO $tableName (`" . implode('`,`', $fields) . "`) VALUES "; 
    $placeHolr = array_fill(0, count($fields), "?"); 
    $qPart = array_fill(0, count($rows), "(" . implode(',', $placeHolr) . ")"); 
    $query .= implode(",", $qPart); 

    $pdo = self::getPDOFromEm($em, $container); 
    $stmt = $pdo->prepare($query); 
    $i = 1; 
    foreach ($rows as $row) { 
     $row['created_at'] = date("Y-m-d H:i:s"); 
     foreach ($fields as $f) { 
      if (!isset($row[$f])) { 
       $row[$f] = null; 
      } 
      $stmt->bindValue($i++, $row[$f]); 
     } 
    } 

    $result = $stmt->execute(); 

    if ($result == false) { 
     $str = print_r($stmt->errorInfo(), true); 
     throw new \Exception($str); 
    } 

    $stmt->closeCursor(); 
    $pdo = null; 
} 

/** 
* Replace old rows in Mysql DB. 
* 
* @param string $date Date. 
*/ 
public static function replace($em, $container, $tableName, $fields, $rows, $extraFieldValues = null) 
{ 
    if ($extraFieldValues != null) { 
     $fields = array_unique(array_merge($fields, array_keys($extraFieldValues))); 
    } 

    $query = "REPLACE INTO $tableName (`" . implode('`,`', $fields) . "`) VALUES "; 
    $placeHolr = array_fill(0, count($fields), "?"); 
    $qPart = array_fill(0, count($rows), "(" . implode(',', $placeHolr) . ")"); 
    $query .= implode(",", $qPart); 

    $pdo = self::getPDOFromEm($em, $container); 
    $stmt = $pdo->prepare($query); 
    $i = 1; 
    foreach ($rows as $row) {    
     if ($extraFieldValues != null) { 
      $row = array_merge($row, $extraFieldValues); 
     } 
     foreach ($fields as $f) { 
      $stmt->bindValue($i++, $row[$f]); 
     }       
    } 
    $stmt->execute(); 
    if (!$stmt) { 
     throw new \Exception("PDO::errorInfo():" . print_r($stmt->errorInfo(), true)); 
    } 
    $stmt->closeCursor(); 
    $pdo = null; 
} 
Cuestiones relacionadas