Nie sądzę, że Zend_Db obsługuje wstawianie wielu wierszy.
Ale jeśli masz tylko dwa rzędy lub trochę więcej, możesz po prostu użyć pętli.
foreach ($data as $row)
{
$db->insert('table', $row)
}
Bill Karwin , były programista Zend Framework, napisał to na Nabble jakiś czas temu :
Zestawy wierszy są w zasadzie obiektem kolekcji, więc dodałbym metody do tej klasy, aby umożliwić dodawanie wierszy do zestawu. Więc powinieneś być w stanie to zrobić:
// 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();
Przekazywanie liczby całkowitej do metody createRowset() w celu utworzenia N pustych wierszy nie ma sensu. Musiałbyś po prostu przejść przez nie, aby mimo wszystko wypełnić je wartościami. Równie dobrze możesz więc napisać pętlę, aby utworzyć i wypełnić poszczególne wiersze danymi aplikacji, a następnie dodać je do kolekcji.
$rowset = $table->createRowset();
foreach ($appData as $tuple)
{
$row = $table->createRow($tuple);
$rowset->addRow($row);
}
$rowset->save();
Zezwolenie na przekazywanie tablicy tablic do metody createRowset() ma sens, ponieważ byłoby to zgodne z użyciem przekazywania krotki do metody createRow().
$rowset = $table->createRowset($appData); // pass array of tuples
To wykona tę samą pętlę, co w poprzednim przykładzie powyżej (z wyjątkiem save() na końcu), tworząc nowy zestaw wierszy z nowych wierszy, gotowy do save()d.
W SQL są dwa sposoby na poprawę wydajności wstawiania danych:
-
Użyj pojedynczej instrukcji INSERT z wieloma wierszami:
INSERT INTO t (col1, col2, col3) WARTOŚCI (1, 2, 3), (4, 5, 6), (7, 8, 9);
-
Przygotuj instrukcję INSERT i wykonaj ją wielokrotnie:
PRZYGOTOWANIE WSTAWIĆ W WARTOŚCI t (col1, col2, col3) (?, ?, ?);WYKONAJ 1, 2, 3WYKONAJ 4, 5, 6WYKONAJ 7, 8, 9
Jednak obsługa któregokolwiek z tych ulepszeń zwiększyłaby złożoność klas Row i Rowset. Wynika to z wewnętrznego sposobu, w jaki bieżąca klasa Zend_Db_Table_Row rozróżnia wiersze, które muszą być INSERT lub UPDATE, kiedy wywołujesz save(). To rozróżnienie jest zawarte w obiekcie Row, więc zestaw wierszy nie wie, czy poszczególne wiersze są nowymi wierszami, czy zmodyfikowanymi kopiami istniejących wierszy. Dlatego, aby klasa Rowset oferowała wielowierszową metodę save(), która używa wydajniejszego języka SQL, zarządzanie brudnymi danymi musiałoby zostać całkowicie zrefaktoryzowane. Łatwiejszym rozwiązaniem jest iteracja Rowset przez jego wiersze, wywołując save() na każdym z nich. Jest to lepsze dla enkapsulacji OO, chociaż nie pomaga zoptymalizować SQL pod kątem wstawiania zestawu wierszy.
W każdym razie naprawdę rzadko zdarza się zbiorcze ładowanie wielu wierszy danych w typowym żądaniu sieci Web, gdy istnieje największe zapotrzebowanie na wydajny SQL. Różnica w wydajności dla małej liczby rzędów jest niewielka, więc byłaby to zauważalna poprawa tylko wtedy, gdy ładujesz dużą liczbę rzędów. Jeśli tak jest, i tak nie powinieneś używać INSERT, powinieneś użyć instrukcji LOAD DATA MySQL lub równoważnej funkcji, jeśli używasz innej marki RDBMS. INSERT zwykle nie jest najskuteczniejszym wyborem do ładowania dużej ilości danych.
Jeśli chodzi o zwrot kluczy wygenerowanych automatycznie, nie zawracałbym sobie głowy. Zauważ, że jeśli używasz zwykłego SQL (na przykład w mysql CLI) i wstawiasz wiele wierszy w pojedynczej instrukcji INSERT, możesz uzyskać tylko ostatnią wygenerowaną wartość identyfikatora, a nie wartości identyfikatora dla wszystkich wstawionych wierszy. To jest zachowanie SQL; dotyczy to każdego języka i dowolnej struktury.
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
Jeśli potrzebujesz identyfikatora dla każdego wiersza, powinieneś napisać pętlę i wstawiać wiersze pojedynczo, pobierając wygenerowany identyfikator po każdym wstawieniu wiersza.