Fügen Sie mehrere Zeilen über ein PHP-Array in mysql ein

Ich übergebe ein großes Dataset in eine MySQL-Tabelle über PHP mit Einfügebefehlen und ich frage mich, ob es möglich ist, etwa 1000 Zeilen gleichzeitig über eine Abfrage einzufügen, außer dass jeder Wert am Ende einer Meile langen Zeichenfolge angehängt wird und dann es ausführend. Ich benutze das CodeIgniter-Framework, sodass seine functionen auch für mich verfügbar sind.

   

    Das Zusammenstellen einer INSERT statement mit mehreren Zeilen ist in MySQL viel schneller als eine INSERT statement pro Zeile.

    Allerdings scheint es, als ob Sie in PHP Probleme mit der Zeichenfolgenbehandlung bekommen könnten, was wirklich ein Algorithmusproblem ist, kein Sprachproblem. Wenn Sie mit großen Strings arbeiten, möchten Sie unnötiges Kopieren minimieren. In erster Linie bedeutet dies, dass Sie die Verkettung vermeiden möchten. Die schnellste und speichereffizienteste Methode zum Erstellen einer großen Zeichenfolge, z. B. zum Einfügen von Hunderten von Zeilen, besteht darin, die function implode() und die Array-Zuweisung zu nutzen.

     $sql = array(); foreach( $data as $row ) { $sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')'; } mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql)); 

    Der Vorteil dieses Ansatzes besteht darin, dass Sie die SQL-statement, die Sie bisher mit jeder Verkettung zusammengestellt haben, nicht kopieren und neu kopieren. Stattdessen tut PHP dies einmal in der implode() statement. Das ist ein großer Gewinn.

    Wenn Sie viele zusammenzufügende Spalten haben und eine oder mehrere sehr lang sind, können Sie auch eine innere Schleife erstellen, um das Gleiche zu tun, und implode() , um die Werte-Klausel dem äußeren Array zuzuordnen.

    Mehrfacheinfügung / Stapeleinfügung wird jetzt von Codeigniter unterstützt. Ich hatte dasselbe Problem. Obwohl es sehr spät für die Beantwortung der Frage ist, wird es jemandem helfen. Deshalb beantworte ich diese Frage.

     $data = array( array( 'title' => 'My title' , 'name' => 'My Name' , 'date' => 'My date' ), array( 'title' => 'Another title' , 'name' => 'Another Name' , 'date' => 'Another date' ) ); $this->db->insert_batch('mytable', $data); // Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date') 

    Sie können die Abfrage zum Einfügen einer Zeile mit der mysqli_stmt-class vorbereiten und dann über das Datenfeld iterieren. Etwas wie:

     $stmt = $db->stmt_init(); $stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)"); foreach($myarray as $row) { $stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']); $stmt->execute(); } $stmt->close(); 

    Dabei sind ‘idsb’ die Typen der Daten, die Sie binden (int, double, string, blob).

    Ich weiß, das ist eine alte Frage, aber ich habe gerade gelesen und dachte, ich würde hinzufügen, was ich woanders gefunden habe:

    mysqli in PHP 5 ist ein Objekt mit einigen guten functionen, mit denen Sie die Einfügezeit für die obige Antwort beschleunigen können:

     $mysqli->autocommit(FALSE); $mysqli->multi_query($sqlCombined); $mysqli->autocommit(TRUE); 

    Autocommit beim Einfügen von vielen Zeilen zu deaktivieren beschleunigt das Einfügen, also schalte es aus, führe dann wie oben beschrieben aus, oder mache einfach eine Zeichenkette (sqlCombined), die viele Einfügeanweisungen durch Semikolons und Multi-Queries getrennt behandelt.

    Hoffe das hilft jemandem Zeit zu sparen (Suchen und Einfügen!)

    R

    Sie könnten immer die LOAD DATA von LOAD DATA :

     LOAD DATA LOCAL INFILE '/full/path/to/file/foo.csv' INTO TABLE `footable` FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n' 

    Masseneinfügungen vorzunehmen, anstatt eine Reihe von INSERT statementen zu verwenden.

    Nun, Sie möchten nicht 1000 Query-Aufrufe ausführen, aber das ist in Ordnung:

     $stmt= array( 'array of statements' ); $query= 'INSERT INTO yourtable (col1,col2,col3) VALUES '; foreach( $stmt AS $k => $v ) { $query.= '(' .$v. ')'; // NOTE: you'll have to change to suit if ( $k !== sizeof($stmt)-1 ) $query.= ', '; } $r= mysql_query($query); 

    Abhängig von Ihrer Datenquelle ist das Auffüllen des Arrays möglicherweise so einfach wie das Öffnen einer Datei und das Speichern der Inhalte in einem Array über die file() .

     $query= array(); foreach( $your_data as $row ) { $query[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')'; } mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $query)); 

    Ich habe eine class erstellt, die mehrere Zeilen ausführt und folgendermaßen verwendet wird:

     $pdo->beginTransaction(); $pmi = new PDOMultiLineInserter($pdo, "foo", array("a","b","c","e"), 10); $pmi->insertRow($data); // .... $pmi->insertRow($data); $pmi->purgeRemainingInserts(); $pdo->commit(); 

    wo die class wie folgt definiert ist:

     class PDOMultiLineInserter { private $_purgeAtCount; private $_bigInsertQuery, $_singleInsertQuery; private $_currentlyInsertingRows = array(); private $_currentlyInsertingCount = 0; private $_numberOfFields; private $_error; private $_insertCount = 0; /** * Create a PDOMultiLine Insert object. * * @param PDO $pdo The PDO connection * @param type $tableName The table name * @param type $fieldsAsArray An array of the fields being inserted * @param type $bigInsertCount How many rows to collect before performing an insert. */ function __construct(PDO $pdo, $tableName, $fieldsAsArray, $bigInsertCount = 100) { $this->_numberOfFields = count($fieldsAsArray); $insertIntoPortion = "REPLACE INTO `$tableName` (`".implode("`,`", $fieldsAsArray)."`) VALUES"; $questionMarks = " (?".str_repeat(",?", $this->_numberOfFields - 1).")"; $this->_purgeAtCount = $bigInsertCount; $this->_bigInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks.str_repeat(", ".$questionMarks, $bigInsertCount - 1)); $this->_singleInsertQuery = $pdo->prepare($insertIntoPortion.$questionMarks); } function insertRow($rowData) { // @todo Compare speed // $this->_currentlyInsertingRows = array_merge($this->_currentlyInsertingRows, $rowData); foreach($rowData as $v) array_push($this->_currentlyInsertingRows, $v); // if (++$this->_currentlyInsertingCount == $this->_purgeAtCount) { if ($this->_bigInsertQuery->execute($this->_currentlyInsertingRows) === FALSE) { $this->_error = "Failed to perform a multi-insert (after {$this->_insertCount} inserts), the following errors occurred:".implode('
    ', $this->_bigInsertQuery->errorInfo()); return false; } $this->_insertCount++; $this->_currentlyInsertingCount = 0; $this->_currentlyInsertingRows = array(); } return true; } function purgeRemainingInserts() { while ($this->_currentlyInsertingCount > 0) { $singleInsertData = array(); // @todo Compare speed - http://www.evardsson.com/blog/2010/02/05/comparing-php-array_shift-to-array_pop/ // for ($i = 0; $i < $this->_numberOfFields; $i++) $singleInsertData[] = array_pop($this->_currentlyInsertingRows); array_reverse($singleInsertData); for ($i = 0; $i < $this->_numberOfFields; $i++) array_unshift($singleInsertData, array_pop($this->_currentlyInsertingRows)); if ($this->_singleInsertQuery->execute($singleInsertData) === FALSE) { $this->_error = "Failed to perform a small-insert (whilst purging the remaining rows; the following errors occurred:".implode('
    ', $this->_singleInsertQuery->errorInfo()); return false; } $this->_currentlyInsertingCount--; } } public function getError() { return $this->_error; } }

    Verwenden Sie Stapel in Codezeichen einfügen, um mehrere Datenzeilen einzufügen.

     $this->db->insert_batch('tabname',$data_array); // $data_array holds the value to be inserted 

    Sie können es mit mehreren Möglichkeiten im Codeigniter zB machen

    Erste Nach-Schleife

     foreach($myarray as $row) { $data = array("first"=>$row->first,"second"=>$row->sec); $this->db->insert('table_name',$data); } 

    Zweiter – Nach Einfügemarke

     $data = array( array( 'first' => $myarray[0]['first'] , 'second' => $myarray[0]['sec'], ), array( 'first' => $myarray[1]['first'] , 'second' => $myarray[1]['sec'], ), ); $this->db->insert_batch('table_name', $data); 

    Dritter Weg – Durch mehrfaches Wertdurchlauf

     $sql = array(); foreach( $myarray as $row ) { $sql[] = '("'.mysql_real_escape_string($row['first']).'", '.$row['sec'].')'; } mysql_query('INSERT INTO table (first, second) VALUES '.implode(',', $sql)); 

    Ich habe diese einfache function erstellt, die Sie einfach verwenden können. Sie müssen den Tabellennamen ($tbl) , das Tabellenfeld ($insertFieldsArr) an Ihr einfügendes ($insertFieldsArr) ($arr) .

     insert_batch('table',array('field1','field2'),$dataArray); function insert_batch($tbl,$insertFieldsArr,$arr){ $sql = array(); foreach( $arr as $row ) { $strVals=''; $cnt=0; foreach($insertFieldsArr as $key=>$val){ if(is_array($row)){ $strVals.="'".mysql_real_escape_string($row[$cnt]).'\','; } else{ $strVals.="'".mysql_real_escape_string($row).'\','; } $cnt++; } $strVals=rtrim($strVals,','); $sql[] = '('.$strVals.')'; } $fields=implode(',',$insertFieldsArr); mysql_query('INSERT INTO `'.$tbl.'` ('.$fields.') VALUES '.implode(',', $sql)); } 

    Obwohl es zu spät ist, diese Frage zu beantworten. Hier sind meine Antworten auf dasselbe.

    Wenn Sie CodeIgniter verwenden, können Sie integrierte Methoden verwenden, die in der class query_builder definiert sind.

    $ this-> db-> insert_batch ()

    Generiert basierend auf den von Ihnen angegebenen Daten eine Einfügezeichenfolge und führt die Abfrage aus. Sie können entweder ein Array oder ein Objekt an die function übergeben. Hier ist ein Beispiel mit einem Array:

     $data = array( array( 'title' => 'My title', 'name' => 'My Name', 'date' => 'My date' ), array( 'title' => 'Another title', 'name' => 'Another Name', 'date' => 'Another date' ) 

    );

     $this->db->insert_batch('mytable', $data); // Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date') 

    Der erste Parameter enthält den Tabellennamen, der zweite einen assoziativen Wertebereich.

    Weitere Informationen zu query_builder finden Sie hier

     use this in codeigniter for multiple data insertion $data = array( array( 'title' => 'My title' , 'name' => 'My Name' , 'date' => 'My date' ), array( 'title' => 'Another title' , 'name' => 'Another Name' , 'date' => 'Another date' ) ); $this->db->insert_batch('mytable', $data); // Produces: INSERT INTO mytable (title, name, date) VALUES ('My title', 'My name', 'My date'), ('Another title', 'Another name', 'Another date')