sql >> Database >  >> RDS >> Mysql

Hoe voeg ik meer dan één rij toe met Zend_Db?

Ik denk niet dat Zend_Db het invoegen van meerdere rijen ondersteunt.

Maar als je maar twee rijen of iets meer hebt, kun je gewoon een lus gebruiken.

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

Bill Karwin , een voormalig Zend Framework-ontwikkelaar, schreef dit op Nabble enige tijd geleden :

Rijensets zijn in feite een verzamelingsobject, dus ik zou methoden aan die klasse toevoegen om rijen aan de set toe te voegen. Dus je zou dit moeten kunnen doen:

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

Het heeft geen zin om een ​​geheel getal door te geven aan createRowset() om N lege rijen te maken. Je zou ze gewoon moeten doorlopen om ze toch met waarden te vullen. U kunt dus net zo goed een lus schrijven om afzonderlijke rijen te maken en te vullen met toepassingsgegevens, en deze vervolgens aan de verzameling toe te voegen.

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

Het is logisch om een ​​array van arrays door te geven aan createRowset(), aangezien dit consistent zou zijn met het gebruik van het doorgeven van een tuple aan createRow().

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

Dit zou dezelfde lus uitvoeren als het vorige voorbeeld hierboven (behalve de save() aan het einde), waardoor een nieuwe rijenset met nieuwe rijen wordt gemaakt, klaar om te worden opgeslagen()d.

Er zijn twee manieren in SQL om de efficiëntie van het invoegen van gegevens te verbeteren:

  1. Gebruik een enkele INSERT-instructie met meerdere rijen:

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

  2. Bereid een INSERT-instructie voor en voer deze meerdere keren uit:

    VOORBEREIDEN INVOEREN IN t (col1, col2, col3) WAARDEN (?, ?, ?);UITVOEREN 1, 2, 3UITVOEREN 4, 5, 6UITVOEREN 7, 8, 9

Het ondersteunen van een van deze verbeteringen zou de klassen Row en Rowset echter complexer maken. Dit komt door de interne manier waarop de huidige Zend_Db_Table_Row klasse onderscheid maakt tussen een rij die moet worden INSERTed of UPDATEd wanneer je save() aanroept. Dit onderscheid wordt ingekapseld door het Row-object, zodat de rijenset niet weet of de afzonderlijke rijen nieuwe rijen zijn of gewijzigde kopieën van bestaande rijen. Om ervoor te zorgen dat de klasse Rowset een methode voor opslaan met meerdere rijen () biedt die efficiëntere SQL gebruikt, zou het beheer van vuile gegevens volledig moeten worden herzien. De eenvoudigere oplossing is dat de rijenset zijn rijen itereert en save() op elke rij aanroept. Dit is beter voor OO-inkapseling, hoewel het niet helpt bij het optimaliseren van SQL voor het invoegen van een rijenset.

Hoe dan ook, het is zeldzaam om veel rijen gegevens in bulk te laden in een typisch webverzoek, wanneer er de grootste behoefte is aan efficiënte SQL. Het verschil in efficiëntie voor een klein aantal rijen is klein, dus het zou alleen een merkbare verbetering zijn als u een groot aantal rijen in bulk laadt. Als dat het geval is, zou u INSERT sowieso niet moeten gebruiken, u zou de LOAD DATA-instructie van MySQL moeten gebruiken, of een vergelijkbare functie als u een ander RDBMS-merk gebruikt. INSERT is meestal niet de meest efficiënte keuze voor het laden van veel gegevens.

Wat betreft het retourneren van automatisch gegenereerde sleutels, zou ik me niet druk maken. Merk op dat als u gewone SQL gebruikt (bijvoorbeeld in de mysql CLI) en u meerdere rijen invoegt in een enkele INSERT-instructie, u alleen de laatst gegenereerde id-waarde kunt krijgen, niet de id-waarden voor alle ingevoegde rijen. Dit is SQL-gedrag; het geldt voor elke taal of elk raamwerk.

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

Als u de id voor elke rij nodig heeft, moet u een lus schrijven en de rijen één voor één invoegen, waarbij u de gegenereerde id ophaalt na elke ingevoegde rij.



  1. Unieke beperking voor meerdere kolommen

  2. Converteer hex naar binair in MySQL

  3. Hoe MySQL hoofdletterongevoelig en accentongevoelig werkt in UTF-8

  4. mysql importeren op windows