sql >> Databasteknik >  >> RDS >> Mysql

Hur lägger jag till mer än en rad med Zend_Db?

Jag tror inte att Zend_Db stöder infogning av flera rader.

Men om du bara har två rader eller lite fler kan du bara använda en slinga.

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

Bill Karwin , en före detta Zend Framework-utvecklare, skrev det här på Nabble för en tid sedan :

Raduppsättningar är i grunden ett samlingsobjekt, så jag skulle lägga till metoder till den klassen för att tillåta rader att läggas till i uppsättningen. Så du borde kunna göra detta:

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

Det är ingen mening att skicka ett heltal till createRowset() för att skapa N tomma rader. Du skulle bara behöva iterera igenom dem för att fylla dem med värden ändå. Så du kan lika gärna skriva en loop för att skapa och fylla i enskilda rader med applikationsdata och sedan lägga till dem i samlingen.

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

Det är vettigt att tillåta att en array av arrayer skickas till createRowset(), eftersom detta skulle stämma överens med användningen av att skicka en tupel till createRow().

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

Detta skulle utföra samma loop som föregående exempel ovan (förutom save() i slutet), skapa en ny raduppsättning av nya rader, redo att sparas()d.

Det finns två sätt i SQL att förbättra effektiviteten för att infoga data:

  1. Använd en enda INSERT-sats med flera rader:

    INSERT I t (col1, col2, col3) VÄRDEN (1, 2, 3), (4, 5, 6), (7, 8, 9);

  2. Förbered en INSERT-sats och kör den flera gånger:

    FÖRBERED INSERT I t (kol1, kol2, kol3) VÄRDEN (?, ?, ?); UTFÖR 1, 2, 3 UTFÖR 4, 5, 6 UTFÖR 7, 8, 9

Men att stödja någon av dessa förbättringar skulle göra klasserna Row och Rowset mer komplexa. Detta beror på det interna sättet som den aktuella Zend_Db_Table_Row-klassen skiljer mellan en rad som behöver INSERT eller UPPDATERAS när du anropar save(). Denna distinktion är inkapslad av Row-objektet, så Rowset vet inte om de individuella raderna är nya rader eller modifierade kopior av befintliga rader. För att klassen Rowset ska erbjuda en multi-row save()-metod som använder mer effektiv SQL, måste hanteringen av smutsiga data omfaktoreras helt. Den enklaste lösningen är att raduppsättningen itererar över sina rader och anropar save() på var och en. Detta är bättre för OO-inkapsling, men det hjälper inte att optimera SQL för att infoga en raduppsättning.

I vilket fall som helst är det verkligen sällsynt att massladda många rader med data i en typisk webbförfrågan, när det finns det största behovet av effektiv SQL. Skillnaden i effektivitet för ett litet antal rader är liten, så det skulle vara en märkbar förbättring endast om du bulklastar ett stort antal rader. Om så är fallet bör du inte använda INSERT ändå, du bör använda MySQL:s LOAD DATA-sats, eller motsvarande funktion om du använder ett annat RDBMS-märke. INSERT är vanligtvis inte det mest effektiva valet för att ladda massor av data.

När det gäller att returnera automatiskt genererade nycklar, skulle jag inte bry mig. Observera att om du använder vanlig SQL (i mysql CLI till exempel), och du infogar flera rader i en enda INSERT-sats, kan du bara få det senast genererade id-värdet, inte id-värdena för alla infogade rader. Detta är SQL-beteende; det är sant för alla språk eller ramverk.

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

Om du behöver id:t för varje rad, bör du skriva en loop och infoga raderna en i taget och hämta det genererade id:t efter varje infogat rad.



  1. Reserverat ord i kolumnnamn - infoga i MySQL

  2. Varför Oracle 10g inte klagar på kolumn tvetydighet?

  3. Välj data mellan två datum?

  4. SQL gruppera efter datum, men få datum utan poster också