sql >> Base de Datos >  >> RDS >> Mysql

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

No creo que Zend_Db admita la inserción de varias 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 algún 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 se agreguen filas al conjunto. Así que 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 número entero a createRowset() para crear N filas vacías. De todos modos, solo tendría que iterar a través de ellos para llenarlos con valores. Por lo tanto, también podría escribir un ciclo 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 se pase una matriz de matrices a createRowset(), ya que esto sería consistente con el uso de pasar una tupla a createRow().

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

Esto realizaría el mismo bucle que el ejemplo anterior (excepto por save() al final), creando un nuevo conjunto de filas nuevas, listas para ser save()d.

Hay dos formas en SQL para mejorar la eficiencia de la inserción de datos:

  1. Use una sola instrucción INSERT con varias 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:

    PREPARAR INSERTAR EN t (col1, col2, col3) VALORES (?, ?, ?); 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 INSERTARSE o ACTUALIZARSE cuando llama a save(). Esta distinción está encapsulada por el objeto Row, por lo que Rowset no sabe si las filas individuales son filas nuevas o copias modificadas de filas existentes. Por lo tanto, para que la clase Rowset ofrezca un método save() de varias filas que use SQL más eficiente, la administración de datos sucios tendría que refactorizarse por completo. La solución más fácil es que el Rowset itere sobre sus filas, llamando a save() en cada una. Esto es mejor para la encapsulación OO, aunque no ayuda a optimizar SQL para insertar un conjunto de filas.

En cualquier caso, es realmente raro cargar muchas filas de datos en una solicitud web típica, cuando existe la mayor necesidad de SQL eficiente. La diferencia en la eficiencia para una pequeña cantidad de filas es pequeña, por lo que sería una mejora notable solo si está cargando de forma masiva una gran cantidad de filas. Si ese es el caso, no debería usar INSERT de todos modos, debería usar la declaració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.

Con respecto a la devolución de claves generadas automáticamente, no me molestaría. Tenga en cuenta que si usa SQL simple (en mysql CLI, 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 identificación para todas las filas insertadas. Este es el comportamiento de SQL; es cierto para cualquier lenguaje o cualquier 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 ciclo e insertar las filas una a la vez, recuperando la identificación generada después de cada fila insertada.