SALT > Manuel > Tutoriel > Base de données > API Query >
L'insertion de nouveaux objets se fait en 3 étapes : Il est également possible d'insérer plusieurs objets provenant d'une requête SELECT, soit en les récupérant pour les modifier avant, soit directement.

Création d'un nouvel objet

<?php
$obj 
= new MonObjet();
$obj->champ1 = ...;
$obj->champ2 = ...;
Il est important de créer un nouvel objet pour chaque ligne que l'on souhaite insérer.
Réutiliser un objet existant ne fonctionnera pas car l'objet aura un état interne incompatible avec une requête d'insertion.

On doit donner une valeur à tout les champs qui ne sont pas nullable et pour lesquels il n'y a pas d'insertion automatique comme avec une colonne en AUTO_INCREMENT ou un champ de type TIMESTAMP.
Les valeurs sont celles des objets PHP, c'est la requête qui s'occupera de la conversion :

Création d'une requête d'insertion

<?php
$insertQuery 
= new InsertQuery($obj);
On peut également passer un tableau d'objet au constructeur, dans ce cas là on inserera tout les objets dans la même requête INSERT, mais ils doivent tous être de la même classe.

Les valeurs de l'objet sont récupérées dans le constructeur de InsertQuery. Une modification sur l'objet après la construction de la requête sera donc sans effet : <?php
$obj
->champ1 'A';
$insertQuery = new InsertQuery($obj);
$obj->champ1 'B'// ignoré
// La requête générée inserera la valeur 'A' pour champ1

Exécution de la requête

<?php
$resultat 
$db->execInsert($insertQuery);
execInsert renvoi la valeur de PDO::lastInsertId(), c'est à dire la dernière valeur utilisée d'une séquence lors de l'insertion. Si la table a une colonne en AUTO_INCREMENT, ce sera la valeur insérée. Dans le cas où plusieurs objets ont été inserés, il s'agit de la dernière valeur uniquement.

Si la requête d'insertion échoue totalement ou partiellement et que le nombre de lignes insérées est différent du nombre d'objets passés en paramètre, la méthode levera une exception de type RowCountException qui contient le nombre de ligne insérées, le nombre de ligne attendues ainsi que le texte de la requête préparée.

Insertion depuis un SELECT

Le paramètre $bindingObject de execQuery() permet d'utiliser le résultat d'une requête pour construire de nouveaux objets, ce qui est un moyen de réaliser l'équivalent d'une requête INSERT...SELECT avec la possibilité de modifier les objets en PHP avant l'insertion.

L'exemple ci-dessous montre comment ajouter un nouvel objet Person pour chaque City existante : <?php
// On construit une requête qui va avoir pour résultat une liste de champ compatibles avec l'objet Person
$q City::query();
$q->select(SqlExpr::_CONCAT('Habitant de '$q->city_name), 'person_name');
$q->selectField('id''city'); // l'ID d'une ville est stocké dans le champ Person->city

echo $q->toSQL().'<br/>'// affiche SELECT CONCAT('Habitant de ', t1.city_name) as person_name, t1.id as city FROM city t1

$r $DBtest->execQuery($qNULLPerson::singleton()); // execution, mais mapping du résultat dans des objets Person

foreach($r->data as $row) {
    echo 
get_class($row).'<br/>'// affiche 'Person' au lieu de 'City'
    
echo 'IS NEW ? '.$row->isNew().'<br/>'// renvoi TRUE pour chaque objet
    
echo 'Name : '.$row->person_name.'<br/>';
}
$i = new InsertQuery($r->data); // Les objets étant nouveaux, on peut les utiliser dans une requête d'insertion
$DBtest->execInsert($i); // va générer la requête :
// INSERT INTO person (person_name, city) VALUES
//         ('Habitant de Bordeaux', 2),
//         ('Habitant de Boston', 6),
//         ('Habitant de Lyon', 3),
//         ('Habitant de New York', 5),
//         ('Habitant de Paris', 1),
//         ('Habitant de Toulouse', 4)

INSERT ... SELECT

Il est également possible de réaliser directement un INSERT INTO ... SELECT en indiquant la requête dans le 2ème paramètre du constructeur de InsertQuery : <?php
$q 
City::query();
$q->select(SqlExpr::_CONCAT('Habitant de '$q->city_name), 'person_name');
$q->selectField('id''city'); // l'ID d'une ville est stocké dans le champ Person->city

$i = new InsertQuery(Person::singleton(), $q); // Le 1er paramètre donne juste le type d'objet a insérer. Le 2ème paramètre est la requête SELECT.
$DBtest->execInsert($i); // va générer la requête :
//     INSERT INTO person (`person_name`, `city`)
//         SELECT CONCAT('Habitant de ', t1.city_name) as `person_name`, t1.id as `city`
//         FROM city t1