zend_db_expr zend query left framework php mysql zend-framework zend-db zend-db-table

php - left - zend query



¿Cómo agrego más de una fila con Zend_Db? (6)

Tengo una matriz con información que se parece más o menos a esto:

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

Y quiero agregar ambas entradas a la Base de datos.

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

no agrega ambas entradas. ¿Qué estoy haciendo mal? ¿Tengo que usar Zend_ Db_Table?

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

funciona por supuesto


Es trabajo.

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

cómo construir múltiples consultas de inserción en zend framework


No creo que Zend_Db admita la inserción de múltiples filas.

Pero si solo tiene dos filas o un poco más, puede usar un bucle.

foreach ($data as $row) { $db->insert(''table'', $row) } Bill Karwin , un antiguo desarrollador de Zend Framework, escribió esto en Nabble hace un tiempo :

Los conjuntos de filas son básicamente un objeto de colección, por lo que agregaría métodos a esa clase para permitir que las filas se agreguen al conjunto. Entonces deberías poder hacer esto:

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

No tiene sentido pasar un entero a createRowset () para crear N filas vacías. Simplemente tendrías que iterar a través de ellos para poblarlos con valores de todos modos. De modo que también podría escribir un bucle para crear y completar filas individuales con datos de la aplicación, y luego agregarlos a la colección.

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

Tiene sentido permitir que una matriz de matrices se pase a createRowset (), ya que esto sería coherente con el uso de pasar una tupla a createRow ().

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

Esto llevaría a cabo el mismo bucle que en el ejemplo anterior anterior (excepto para guardar () al final), creando un nuevo conjunto de filas de filas nuevas, listo para ser save () d.

Hay dos formas en SQL para mejorar la eficacia de insertar datos:

  1. Use una sola instrucción INSERT con múltiples filas:

    INSERTAR EN t (col1, col2, col3) VALORES (1, 2, 3), (4, 5, 6), (7, 8, 9);

  2. Prepare una instrucción INSERT y ejecútela varias veces:

    PREPARE INSERT INTO t (col1, col2, col3) VALUES (?,?,?); EJECUTAR 1, 2, 3 EJECUTAR 4, 5, 6 EJECUTAR 7, 8, 9

Sin embargo, admitir cualquiera de estas mejoras agregaría complejidad a las clases Row y Rowset. Esto se debe a la forma interna en que la clase Zend_Db_Table_Row actual diferencia entre una fila que debe INSERTAR o ACTUALIZAR cuando llama a guardar (). Esta distinción está encapsulada por el objeto Fila, por lo que Rowset no sabe si las filas individuales son nuevas filas o copias modificadas de las filas existentes. Por lo tanto, para que la clase Rowset ofrezca un método save () de varias filas que utiliza SQL más eficiente, la gestión de datos sucios tendría que ser totalmente refactorizada. La solución más fácil es que el Rowset itere sobre sus filas, llamando a save () en cada uno. Esto es mejor para la encapsulación OO, aunque no ayuda a optimizar SQL para insertar un conjunto de filas.

En cualquier caso, es muy raro cargar a granel muchas filas de datos en una solicitud web típica, cuando existe la mayor necesidad de SQL eficiente. La diferencia en la eficiencia para un pequeño número de filas es pequeña, por lo que sería una mejora notable solo si está cargando a granel una gran cantidad de filas. Si ese es el caso, no debe utilizar INSERT de todos modos, debe utilizar la instrucción LOAD DATA de MySQL o una función equivalente si usa otra marca RDBMS. INSERT no suele ser la opción más eficiente para cargar muchos datos.

En cuanto a devolver las llaves generadas automáticamente, no me molestaría. Tenga en cuenta que si utiliza SQL simple (en la CLI de MySQL por ejemplo) e inserta varias filas en una sola instrucción INSERT, solo puede obtener el último valor de identificación generado, no los valores de id para todas las filas insertadas. Este es el comportamiento de SQL; es cierto para cualquier idioma o marco.

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

Si necesita la identificación para cada fila, debe escribir un bucle e insertar las filas de a una por vez, recuperando la identificación generada después de cada fila insertada.


Puede ejecutar cualquier sintaxis SQL que desee, incluidas las INSERT múltiples filas, a través del método Zend_Db_Adapter_Abstract::query() .

Pero los métodos de las clases Zend_Db_Table y Zend_Db_Table_Rowset no tienen ningún soporte para insertar múltiples filas de una vez.


Si usa ZF2, la solución podría ser así:

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


aquí está mi solución:

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


para insertar múltiples filas, puedes usar Zend_Db

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

(de Bill Karwin)

en su caso, podemos cambiar eso a este código:

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

para generar estos ''(?), (?)'' dinámicamente, en caso de que los datos sean dinámicos, puedes intentar usar este fragmento de código:

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

espero que esto ayude

saludos, Riki Risnandar