Question

EDIT: Ce titre de la question était à l'origine: Comment ne Doctrine sait dernière id Inséré dans MySQL et était liée à Doctrine ORM mappeur?. Après quelques recherches, j'ai découvert que cette question n'a rien à voir Doctrine mais PDO_MySQL , API MySQL C et enfin - à MySQL client-serveur la communication. J'ai décidé de changer le titre, alors peut-être que quelqu'un va trouver réponse à la question de son /.

Pour ceux qui n'utilisent pas Doctrine: J'étais curieux, pourquoi ci-dessous:

mysql_query("INSERT INTO category (name) VALUES('cat')");
echo mysql_insert_id();

ou similaire:

$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();

conduira à une seule position (sans SELECT LAST_INSERT_ID() séparée) dans le journal:

1701 Query    INSERT INTO category (name) VALUES ('cat')

Question d'origine:

J'ai 2 tables:

category(id,name)
product(id, name, categoryId)

Je crée nouvel objet de la catégorie et de l'objet produit. J'affecté objet catégorie à l'objet produit. Je ne l'ai pas mis les ids:

$product = new Product();
$product->name = 'asdf';

$category = new Category();
$category->name = 'cat';

$product->Category = $category;

Après que je rougis la connexion et vérifiez les journaux MySQL:

1684 Query  START TRANSACTION
1684 Query  INSERT INTO category (name) VALUES ('cat')
1684 Query  INSERT INTO product (name, categoryid) VALUES ('asdf', '312')
1684 Query  COMMIT

Comment savoir Doctrine, que l'identifiant de la catégorie nouvellement créée est 312? Il n'y a rien d'autre dans les journaux.

Était-ce utile?

La solution

Je l'ai fait quelques recherches et parcourir un code source, donc ma réponse pourrait être un peu de mal à peu et pas précis.

Tout d'abord, ce n'est pas vraiment lié à Doctrine . Doctrine utilise PDO_MYSQL . Mais en interne PDO_MYSQL utilise la même chose que la fonction mysql_insert_id - native API MySQL C fonction -. mysql_insert_id

La raison pour laquelle il n'y a pas de mensonges de SELECT LAST_INSERT_ID() séparés dans le fait, qu'après l'instruction est exécutée (dans mon exemple INSERT), répond serveur avec des données et d'autres choses incluses dans OK Packet ), y compris insert_id. Alors, quand nous mysql_insert_id() de feu, nous ne sommes pas se connecter au serveur, de recevoir insert_id - bibliothèque MySQL n'a pas besoin de le faire - il a déjà cette valeur stockée de la dernière exécution de requête (au moins je pense après l'analyse du fichier libmysql.c)

OK Packet est décrit ici: MySQL Packets réponse générique - OK paquet

Autres conseils

last_insert_id ne fonctionne que pour les colonnes de AUTO_INCREMENT. Il ne fonctionnera pas si vous insérez une valeur manuellement dans la colonne AUTO_INCREMENT.

La doctrine fonctionnera parce qu'elle est tout comme l'attribution d'un NULL à lui (même si vous n'écrire spécifiquement que). Cela déclenche l'incrémentation automatique et fournir une valeur pour last_insert_id().

J'ai inclus un jpg ici pour que vous puissiez le voir. Espérons que cela aide!

entrer image description ici

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top