Как добавить несколько строк в Zend_Db?

У меня есть массив с информацией, которая выглядит примерно так:

$data[] = array('content'=>'asd'); $data[] = array('content'=>'asdf'); 

И я хочу добавить обе записи в базу данных.

 $db->insert('table', $data); 

не добавляет обе записи. Что я делаю не так? Должен ли я использовать Zend_ Db_Table?

 $data = array('content'=>'asdf'); $db->insert('table', $data); 

конечно же, работы

Solutions Collecting From Web of "Как добавить несколько строк в Zend_Db?"

Я не думаю, что Zend_Db поддерживает вставку нескольких строк.

Но если у вас всего две строки или еще немного, вы можете просто использовать цикл.

 foreach ($data as $row) { $db->insert('table', $row) } 


Билл Карвин , бывший разработчик Zend Framework, написал об этом в Nabble некоторое время назад :

Строки – это в основном объект коллекции, поэтому я бы добавил методы к этому классу, чтобы добавить строки в набор. Поэтому вы должны это сделать:

 // creates a rowset collection with zero rows $rowset = $table->createRowset(); // creates one row with unset values $row = $table->createRow(); // adds one row to the rowset $rowset->addRow($row); // iterates over the set of rows, calling save() on each row $rowset->save(); 

Нет смысла передавать целое число createRowset () для создания N пустых строк. Вам просто нужно будет проходить через них, чтобы все равно заполнить их значениями. Таким образом, вы можете написать цикл для создания и заполнения отдельных строк данными приложения, а затем добавить их в коллекцию.

 $rowset = $table->createRowset(); foreach ($appData as $tuple) { $row = $table->createRow($tuple); $rowset->addRow($row); } $rowset->save(); 

Имеет смысл разрешить передачу массива массивов createRowset (), поскольку это будет соответствовать использованию передачи кортежа createRow ().

 $rowset = $table->createRowset($appData); // pass array of tuples 

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

В SQL есть два способа повысить эффективность вставки данных:

  1. Используйте один оператор INSERT с несколькими строками:

    INSERT INTO t (col1, col2, col3) ЗНАЧЕНИЯ (1, 2, 3), (4, 5, 6), (7, 8, 9);

  2. Подготовьте инструкцию INSERT и выполните ее несколько раз:

    ПОДГОТОВЬТЕ ВСТАВИТЬ В t (col1, col2, col3) ЗНАЧЕНИЯ (?,?,?); ВЫПОЛНИТЬ 1, 2, 3 ВЫПОЛНИТЬ 4, 5, 6 ВЫПОЛНИТЬ 7, 8, 9

Однако поддержка любого из этих улучшений добавила бы сложности в классы Row и Rowset. Это связано с тем, что текущий класс Zend_Db_Table_Row различает строку, которая должна быть INSERTED или UPDATEd, когда вы вызываете save (). Это различие инкапсулируется объектом Row, поэтому Rowset не знает, являются ли отдельные строки новыми строками или измененными копиями существующих строк. Поэтому для класса Rowset предлагается многострочный метод save (), который использует более эффективный SQL, управление грязными данными должно быть полностью реорганизовано. Более легкое решение состоит в том, что Rowset выполняет итерацию по своим строкам, вызывая save () для каждого из них. Это лучше для инкапсуляции OO, хотя это не помогает оптимизировать SQL для вставки набора строк.

В любом случае, очень редко приходится загружать много строк данных в типичном веб-запросе, когда существует большая потребность в эффективном SQL. Разница в эффективности для небольшого количества строк мала, поэтому это было бы заметным улучшением, только если вы загружаете огромное количество строк. Если это так, вы не должны использовать INSERT в любом случае, вы должны использовать инструкцию LOAD DATA MySQL или эквивалентную функцию, если используете другую марку RDBMS. INSERT обычно не самый эффективный выбор для загрузки большого количества данных.

Что касается возвращения автоматически сгенерированных ключей, я бы не стал беспокоиться. Обратите внимание: если вы используете простой SQL (например, в CLI mysql), и вы вставляете несколько строк в один оператор INSERT, вы можете получить только последнее генерируемое значение id, а не значения id для всех вставленных строк. Это поведение SQL; это верно для любого языка или любой структуры.

 INSERT INTO t (col1, col2, col3) VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9); SELECT LAST_INSERT_ID(); -- returns only the id for the third tuple 

Если вам нужен идентификатор для каждой строки, вы должны написать цикл и вставить строки по одному, извлекая сгенерированный идентификатор после каждой вставленной строки.

Вы можете выполнить любой синтаксис SQL, который вы хотите, включая многострочные INSERT помощью метода Zend_Db_Adapter_Abstract::query() .

Но методы классов Zend_Db_Table и Zend_Db_Table_Rowset не имеют поддержки для вставки нескольких строк за один раз.

для вставки нескольких строк вы можете использовать Zend_Db

 $stmt = $table->getAdapter()->prepare('INSERT INTO tablename (col1, col2, col3) VALUES (?, ?, ?), (?, ?, ?)'); $stmt->execute( array($value1, $value2, $value3, $value4, $value5, $value6) ); 

(от Билла Карвина)

в вашем случае мы можем изменить это на этот код:

 $data[] = array('content'=>'asd'); $data[] = array('content'=>'asdf'); $stmt = $table->getAdapter()->prepare('INSERT INTO table (col1) VALUES (?), (?)'); $stmt->execute( $data ); 

для генерации этих «(?), (?)» динамически, если данные динамические, вы можете попробовать использовать этот фрагмент:

 $values = implode(',',array_fill(0,count($data),'(?)')); 

надеюсь это поможет

привет, Рики Риснандар

вот мое решение:

 public function saveRows($array) { $vAmount = count($array); $values = array(); $columns = array(); foreach ($array as $colval) { foreach ($colval as $column=>$value) { array_push($values,$value); !in_array($column,$columns) ? array_push($columns,$column) : null; } } $cAmount = count($columns); $values = array_chunk($values, $cAmount); $iValues = ''; $iColumns = implode("`, `", $columns); for($i=0; $i<$vAmount;$i++) $iValues.="('".implode("', '", $values[$i])."')".(($i+1)!=$vAmount ? ',' : null); $data="INSERT INTO `".$this->_name."` (`".$iColumns."`) VALUES ".$iValues; die($data); $this->query($data); } 

Если вы используете ZF2, тогда решение может быть таким:

 $insert = $this->getSql()->insert(); foreach ($values as $value) { $relation = array( 'column_one' => $value, 'column_two' => $value ); $insert->values($relation, Insert::VALUES_MERGE); } $insertRes = $this->executeInsert($insert); 

Это работает.

  $query = 'INSERT INTO ' . $db->quoteIdentifier('table') . ' (`col1`, `col2`) VALUES '; $queryVals = array(); foreach ($data as $row) { foreach($row as &$col) { $col = $db->quote($col); } $queryVals[] = '(' . implode(',', $row) . ')'; } $stmt = $db->query($query . implode(',', $queryVals)); 

как построить несколько запросов вставки в zend framework