Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como adiciono mais de uma linha com Zend_Db?


Eu não acho que Zend_Db suporte a inserção de várias linhas.

Mas se você tiver apenas duas linhas ou um pouco mais, poderá usar um loop.
foreach ($data as $row)
{
    $db->insert('table', $row)
}


Bill Karwin , um ex-desenvolvedor do Zend Framework, escreveu isso no Nabble há algum tempo :
Os conjuntos de linhas são basicamente um objeto de coleção, então eu adicionaria métodos a essa classe para permitir que as linhas fossem adicionadas ao conjunto. Então você deve ser capaz de fazer isso:
// 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(); 

Não faz sentido passar um inteiro para createRowset() para criar N linhas vazias. Você teria apenas que iterar por eles para preenchê-los com valores de qualquer maneira. Portanto, você também pode escrever um loop para criar e preencher linhas individuais com dados do aplicativo e adicioná-las à coleção.
$rowset = $table->createRowset();
foreach ($appData as $tuple) 
{
    $row = $table->createRow($tuple);
    $rowset->addRow($row);
}
$rowset->save();

Faz sentido permitir que um array de arrays seja passado para createRowset(), pois isso seria consistente com o uso de passar uma tupla para createRow().
$rowset = $table->createRowset($appData); // pass array of tuples

Isso executaria o mesmo loop do exemplo anterior (exceto pelo save() no final), criando um novo conjunto de linhas de novas linhas, pronto para ser salvo()d.

Existem duas maneiras no SQL para melhorar a eficiência da inserção de dados:

  1. Use uma única instrução INSERT com várias linhas:

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

  2. Prepare uma instrução INSERT e execute-a várias vezes:

    PREPARE INSERIR EM t (col1, col2, col3) VALORES (?, ?, ?);EXECUTAR 1, 2, 3EXECUTAR 4, 5, 6EXECUTAR 7, 8, 9

No entanto, o suporte a qualquer uma dessas melhorias adicionaria complexidade às classes Row e Rowset. Isso se deve à maneira interna como a classe Zend_Db_Table_Row atual diferencia entre uma linha que precisa ser INSERT ou UPDATE quando você chama save(). Essa distinção é encapsulada pelo objeto Row, portanto, o Rowset não sabe se as linhas individuais são novas linhas ou cópias modificadas de linhas existentes. Portanto, para a classe Rowset oferecer um método save() de várias linhas que usa SQL mais eficiente, o gerenciamento de dados sujos teria que ser totalmente refatorado. A solução mais fácil é o Rowset iterar sobre suas linhas, chamando save() em cada uma. Isso é melhor para o encapsulamento OO, embora não ajude a otimizar o SQL para inserir um conjunto de linhas.

De qualquer forma, é muito raro carregar muitas linhas de dados em massa em uma solicitação da Web típica, quando há maior necessidade de SQL eficiente. A diferença de eficiência para um pequeno número de linhas é pequena, portanto, seria uma melhoria notável apenas se você estivesse carregando em massa um grande número de linhas. Se for esse o caso, você não deveria estar usando INSERT de qualquer maneira, você deveria estar usando a instrução LOAD DATA do MySQL, ou recurso equivalente se você usar outra marca RDBMS. INSERT geralmente não é a escolha mais eficiente para carregar muitos dados.

Em relação ao retorno de chaves geradas automaticamente, eu não me incomodaria. Observe que se você usar SQL simples (na CLI do mysql, por exemplo), e inserir várias linhas em uma única instrução INSERT, você poderá obter apenas o último valor de id gerado, não os valores de id para todas as linhas inseridas. Este é o comportamento SQL; é verdade para qualquer linguagem ou qualquer framework.
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

Se você precisar do id para cada linha, você deve escrever um loop e inserir as linhas uma de cada vez, recuperando o id gerado após cada linha inserida.