Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment puis-je ajouter plus d'une ligne avec Zend_Db ?

Je ne pense pas que Zend_Db supporte l'insertion de plusieurs lignes.

Mais si vous n'avez que deux lignes ou un peu plus, vous pouvez simplement utiliser une boucle.

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

Bill Karwin , un ancien développeur Zend Framework, a écrit ceci sur Nabble il y a quelque temps :

Les ensembles de lignes sont essentiellement un objet de collection, donc j'ajouterais des méthodes à cette classe pour permettre l'ajout de lignes à l'ensemble. Vous devriez donc pouvoir faire ceci :

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

Cela n'a aucun sens de passer un entier à createRowset() pour créer N lignes vides. Vous n'auriez qu'à les parcourir pour les remplir avec des valeurs de toute façon. Vous pouvez donc tout aussi bien écrire une boucle pour créer et remplir des lignes individuelles avec des données d'application, puis les ajouter à la collection.

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

Il est logique d'autoriser la transmission d'un tableau de tableaux à createRowset(), car cela serait cohérent avec l'utilisation de la transmission d'un tuple à createRow().

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

Cela effectuerait la même boucle que l'exemple précédent ci-dessus (sauf pour le save() à la fin), créant un nouvel ensemble de lignes de nouvelles lignes, prêt à être save()d.

Il existe deux manières en SQL d'améliorer l'efficacité de l'insertion de données :

  1. Utilisez une seule instruction INSERT avec plusieurs lignes :

    INSÉRER DANS t (col1, col2, col3) VALEURS (1, 2, 3), (4, 5, 6), (7, 8, 9);

  2. Préparez une instruction INSERT et exécutez-la plusieurs fois :

    PREPARE INSERT INTO t (col1, col2, col3) VALUES (?, ?, ?);EXECUTE 1, 2, 3EXECUTE 4, 5, 6EXECUTE 7, 8, 9

Cependant, la prise en charge de l'une ou l'autre de ces améliorations ajouterait de la complexité aux classes Row et Rowset. Cela est dû à la manière interne dont la classe Zend_Db_Table_Row actuelle différencie une ligne qui doit être INSERT ou UPDATE lorsque vous appelez save(). Cette distinction est encapsulée par l'objet Row, de sorte que le Rowset ne sait pas si les lignes individuelles sont de nouvelles lignes ou des copies modifiées de lignes existantes. Par conséquent, pour que la classe Rowset propose une méthode save() multi-lignes utilisant un SQL plus efficace, la gestion des données modifiées devrait être totalement refactorisée. La solution la plus simple consiste pour le Rowset à itérer sur ses lignes, en appelant save() sur chacune d'elles. C'est mieux pour l'encapsulation OO, même si cela n'aide pas à optimiser SQL pour l'insertion d'un ensemble de lignes.

Dans tous les cas, il est vraiment rare de charger en bloc de nombreuses lignes de données dans une requête Web typique, lorsque le besoin en SQL efficace est le plus grand. La différence d'efficacité pour un petit nombre de lignes est faible, il ne s'agirait donc d'une amélioration notable que si vous chargez en bloc un grand nombre de lignes. Si tel est le cas, vous ne devriez pas utiliser INSERT de toute façon, vous devriez utiliser l'instruction LOAD DATA de MySQL, ou une fonctionnalité équivalente si vous utilisez une autre marque RDBMS. INSERT n'est généralement pas le choix le plus efficace pour charger beaucoup de données.

En ce qui concerne le retour des clés générées automatiquement, je ne m'en soucierais pas. Notez que si vous utilisez du SQL brut (dans la CLI mysql par exemple) et que vous insérez plusieurs lignes dans une seule instruction INSERT, vous ne pouvez obtenir que la dernière valeur d'identifiant générée, pas les valeurs d'identifiant pour toutes les lignes insérées. C'est le comportement SQL ; c'est vrai pour n'importe quel langage ou n'importe quel 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

Si vous avez besoin de l'identifiant pour chaque ligne, vous devez écrire une boucle et insérer les lignes une par une, en récupérant l'identifiant généré après chaque ligne insérée.