2011-12-02 1 views
7

Sto cercando di utilizzare la risposta di statics in this question per le istruzioni preparate. Consente di prendere questo esempio:Come inserire più righe in un database mysql contemporaneamente con istruzioni preparate?

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

In risposta staticsan's implodere l'array è l'aggiunta di tutti i valori nella dichiarazione mysql in modo che, alla fine, siamo in grado di inserire più dati nel database con una sola dichiarazione. Come si farebbe nel mio esempio?

+0

Il vostro esempio ha un numero fisso di parametri, quindi è già risolto. Puoi approfondire il tuo problema un po 'di più? Cosa hai provato fino ad ora? Dovrebbe fondamentalmente funzionare allo stesso modo ma aggiungere più parametri, ad es. in un ciclo 'foreach'. – hakre

+0

È possibile creare istruzioni preparate utilizzando il codice come indicato qui, http://stackoverflow.com/questions/1176352/pdo-prepared-inserts-multiple-rows-in-single-query –

risposta

5

Questo è del tutto valido:

$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(); 

È possibile foreach sopra la matrice di valori da inserire e si legano ed eseguire ogni volta. Non sarà abbastanza veloce come l'inserimento di massa nell'esempio che hai collegato, ma sarà più sicuro.

+1

Grazie, funziona. Ma execute() verrà eseguito per ciascun elemento dell'array, quindi ogni riga verrà inserita nel database separatamente e non tutti allo stesso tempo. Ho ragione? Speravo di vedere una soluzione dove bind_param prima tutti i valori e alla fine eseguirlo una volta. – phpheini

+0

Sì, è corretto, ma il vantaggio principale è l'aumento di velocità fornito dall'istruzione preparata: preparare la dichiarazione una volta e correre più volte è molto più veloce di prepararla ogni volta. –

+0

Questo è ancora più lento di una buona vecchia query 'INSERT' statica, non è vero? Voglio dire, l'esecuzione di query in un ciclo crea un ritardo di ~ 2 ms tra ogni query. Con grandi matrici ci vorrebbe per sempre, no? – NoobishPro

-2

La query si presenta così:

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

sì, ma non per le dichiarazioni preparate. La domanda è, devo scrivere '$ mysqli-> prepare (" INSERIRE in qualcosa (userid, tempo, titolo) VALORI (?,?,?), (?,?,?), (?,? ,?) ");' e quindi 'bind_param ('iisiisiis', $ userid [0], time(), $ title, $ userid [0], time(), $ title [0], $ userid [1], time(), $ title [1], $ userid [2], time(), $ title [2]); ' – phpheini

2

È possibile costruire dichiarazione preparata utilizzando il codice come detto qui,

PDO Prepared Inserts multiple rows in single query

logica PHP sarà un po 'come,

/** 
* 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; 
}