Jeg tror ikke, at Zend_Db understøtter indsættelse af flere rækker.
Men hvis du bare har to rækker eller lidt mere kan du bare bruge en løkke.
foreach ($data as $row)
{
$db->insert('table', $row)
}
Bill Karwin , en tidligere Zend Framework-udvikler, skrev det her på Nabble for noget tid siden :
Rækkesæt er dybest set et samlingsobjekt, så jeg ville tilføje metoder til den klasse for at tillade rækker at blive tilføjet til sættet. Så du burde være i stand til at gøre dette:
// 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 giver ingen mening at sende et heltal til createRowset() for at skabe N tomme rækker. Du skulle bare gentage dem for at fylde dem med værdier alligevel. Så du kan lige så godt skrive en løkke for at oprette og udfylde individuelle rækker med applikationsdata og derefter tilføje dem til samlingen.
$rowset = $table->createRowset();
foreach ($appData as $tuple)
{
$row = $table->createRow($tuple);
$rowset->addRow($row);
}
$rowset->save();
Det giver mening at tillade, at et array af arrays sendes til createRowset(), da dette ville være i overensstemmelse med brugen af at overføre en tuple til createRow().
$rowset = $table->createRowset($appData); // pass array of tuples
Dette ville udføre den samme løkke som det foregående eksempel ovenfor (bortset fra save() i slutningen), og skabe et nyt rækkesæt af nye rækker, klar til at blive save()d.
Der er to måder i SQL at forbedre effektiviteten ved at indsætte data på:
-
Brug en enkelt INSERT-sætning med flere rækker:
INDSÆT I t (col1, col2, col3) VÆRDIER (1, 2, 3), (4, 5, 6), (7, 8, 9);
-
Forbered en INSERT-sætning, og kør den flere gange:
FORBERED INDSÆT I t (kol1, kol2, kol3) VÆRDIER (?, ?, ?); UDFØR 1, 2, 3 UDFØR 4, 5, 6 UDFØR 7, 8, 9
Men at understøtte en af disse forbedringer ville tilføje kompleksitet til Row- og Rowset-klasserne. Dette skyldes den interne måde, hvorpå den aktuelle Zend_Db_Table_Row-klasse skelner mellem en række, der skal INSERTES eller OPDATERES, når du kalder save(). Denne skelnen er indkapslet af Row-objektet, så Rowsettet ved ikke, om de individuelle rækker er nye rækker eller modificerede kopier af eksisterende rækker. For at Rowset-klassen kan tilbyde en multi-row save()-metode, der bruger mere effektiv SQL, skal håndteringen af beskidte data omstruktureres fuldstændigt. Den nemmeste løsning er, at Rowsettet gentager sine rækker og kalder save() på hver enkelt. Dette er bedre til OO-indkapsling, selvom det ikke hjælper med at optimere SQL til indsættelse af et rækkesæt.
Under alle omstændigheder er det virkelig sjældent at masseindlæse mange rækker af data i en typisk webanmodning, når der er det største behov for effektiv SQL. Forskellen i effektivitet for et lille antal rækker er lille, så det ville kun være en mærkbar forbedring, hvis du bulk-loader et stort antal rækker. Hvis det er tilfældet, bør du alligevel ikke bruge INSERT, du skal bruge MySQL's LOAD DATA-sætning eller tilsvarende funktion, hvis du bruger et andet RDBMS-mærke. INSERT er normalt ikke det mest effektive valg til at indlæse masser af data.
Med hensyn til returnering af auto-genererede nøgler, ville jeg ikke gider. Bemærk, at hvis du bruger almindelig SQL (i mysql CLI for eksempel), og du indsætter flere rækker i en enkelt INSERT-sætning, kan du kun få den sidst genererede id-værdi, ikke id-værdierne for alle indsatte rækker. Dette er SQL-adfærd; det gælder for ethvert sprog eller enhver ramme.
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
Hvis du har brug for id'et for hver række, skal du skrive en løkke og indsætte rækkerne en ad gangen, og hente det genererede id efter hver række indsat.