Подтвердить что ты не робот

Вставить несколько строк через php-массив в mysql

Я передаю большой набор данных в таблицу mysql через php, используя команды вставки, и мне интересно, возможно ли его вставить примерно 1000 строк за раз с помощью запроса, отличного от добавления каждого значения в конце мили и затем выполнить его. Я использую фреймворк codeigniter, поэтому его функции также доступны мне.

4b9b3361

Ответ 1

Сборка одного оператора INSERT с несколькими строками в MySQL намного быстрее, чем один оператор INSERT для каждой строки.

Тем не менее, похоже, что вы можете столкнуться с проблемами обработки строк в PHP, что является проблемой алгоритма, а не языковой. В основном, при работе с большими строками вы хотите минимизировать ненужное копирование. Прежде всего, это означает, что вы хотите избежать конкатенации. Самый быстрый и наиболее эффективный в памяти способ создания большой строки, например, для вставки сотен строк в один, заключается в использовании функции implode() и назначения массива.

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

Преимущество такого подхода заключается в том, что вы не копируете и не копируете инструкцию SQL, которую вы собрали до сих пор с каждой конкатенацией; вместо этого PHP делает это один раз в инструкции implode(). Это большая победа.

Если у вас много столбцов для объединения, а один или несколько из них очень длинные, вы также можете создать внутренний цикл для выполнения того же самого действия и использовать implode() для назначения предложения значения внешнему массиву.

Ответ 2

Несколько вставных/пакетных вставок теперь поддерживаются с помощью codeigniter. У меня была такая же проблема. Хотя ответить на вопрос очень поздно, это поможет кому-то. Вот почему ответ на этот вопрос.

$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')

Ответ 3

Вы можете подготовить запрос для вставки одной строки, используя класс mysqli_stmt, а затем перебрать массив данных. Что-то вроде:

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

Где 'idsb' - типы данных, которые вы связываете (int, double, string, blob).

Ответ 4

Я знаю, что это старый запрос, но я просто читал и думал, что добавлю то, что нашел в другом месте:

mysqli в PHP 5 - это ojbect с некоторыми хорошими функциями, которые позволят вам ускорить время вставки для ответа выше:

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

Отключение автообмена при вставке многих строк значительно ускоряет вставку, поэтому отключите его, затем выполните, как указано выше, или просто создайте строку (sqlCombined), в которую входят многие вставные операторы, разделенные полуколонами, и многопроцессор будет обрабатывать они прекрасны.

Надеюсь, это поможет кому-то сэкономить время (поиск и вставка!)

R

Ответ 5

Вы всегда можете использовать mysql LOAD DATA:

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

чтобы делать объемные вставки, а не использовать кучу операторов INSERT.

Ответ 6

Ну, вы не хотите выполнять 1000 запросов, но это нормально:

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

В зависимости от источника данных, заполнение массива может быть таким же простым, как открытие файла и сброс содержимого в массив через file().

Ответ 7

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

Ответ 8

Я создал класс, который выполняет многострочную линию, которая используется следующим образом:

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

где класс определяется следующим образом:

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('<br/>', $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('<br/>', $this->_singleInsertQuery->errorInfo());
                return false;
            }
            $this->_currentlyInsertingCount--;
        }
    }

    public function getError() {
        return $this->_error;
    }
}

Ответ 9

Используйте вставку для вставки в codeigniter для вставки нескольких строк данных.

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

Ответ 10

Вы можете сделать это несколькими способами в codeigniter, например.

Первый По циклу

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

Второй - с помощью вставки

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

Третий путь - через несколько значений

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

Ответ 11

Я создал эту простую функцию, которую вы, ребята, можете легко использовать. Вам нужно будет передать табличное имя ($tbl), table-field ($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));
}

Ответ 12

Хотя слишком поздно ответить на этот вопрос. Вот мой ответ на то же самое.

Если вы используете CodeIgniter, вы можете использовать встроенные методы, определенные в классе query_builder.

$this- > db- > insert_batch()

Создает строку вставки на основе данных, которые вы поставляете, и запускает запрос. Вы можете передать массив или объект функции. Вот пример использования массива:

$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')

Первый параметр будет содержать имя таблицы, второй - ассоциативный массив значений.

Вы можете найти более подробную информацию о query_builder здесь

Ответ 13

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')