2010-11-24 21 views
14

EDITAR: Este título de pregunta era originalmente: ¿Cómo sabe Doctrine la última identificación insertada en MySQL? y se relacionó con Doctrine ORM mapper. Después de algunas excavaciones descubrí que esta pregunta no está relacionada con Doctrine sino a PDO_MySQL, MySQL C API y finalmente - a la comunicación cliente-servidor MySQL. He decidido cambiar el título, por lo que tal vez alguien encuentre la respuesta a la pregunta de él/ella.¿Cómo sabe PDO la última identificación insertada en MySQL?

Para aquellos que no están usando Doctrina: Tenía curiosidad, ¿por qué a continuación:

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

o similar:

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

dará lugar a una sola posición (sin separada SELECT LAST_INSERT_ID()) en el registro:

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

pregunta original:

Tengo 2 tablas:

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

creé nueva categoría de objetos y objetos producto. Asigné un objeto de categoría al objeto del producto. Yo no puse ningún ID:

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

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

$product->Category = $category; 

Después de eso, tiraba la conexión y comprobar los registros de 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 

¿Cómo Doctrina saber, que la categoría de Identificación del recién creado es 312? No hay nada más en los registros.

Respuesta

22

he hecho un poco de investigación y ver algunos código fuente, por lo que mi respuesta podría ser un poco mal y no precisa.

En primer lugar, esto no está realmente relacionado con Doctrine. Doctrine utiliza PDO_MYSQL. Pero internamente PDO_MYSQL utiliza lo mismo que la función mysql_insert_id - MySQL C API función - mysql_insert_id.

La razón por la que no hay separados SELECT LAST_INSERT_ID() radica en el hecho, que después se ejecuta la instrucción (en mi ejemplo INSERT), el servidor responde con los datos y algunas otras cosas incluidas en el paquete OK), incluyendo insert_id. Entonces, cuando disparamos mysql_insert_id() no nos estamos conectando al servidor, para recibir insert_id - la biblioteca mysql no necesita hacer eso - ya tiene este valor almacenado desde la última ejecución de la consulta (al menos eso creo después de analizar el archivo libmysql.c)

Aceptar paquetes se describe aquí: MySQL Generic Response Packets - OK Packet

+0

Gran investigación. – jensgram

+0

Es por eso que podemos usarlo, sin temor a la raza de la consulta. Gracias. – noober

1
+0

Pero eso se reflejaría en el registro, ¿verdad? –

+0

@Pekka Una conjetura sin educación: ¿Se podría configurar el registro para * no * escribir 'SELECT' s? – jensgram

+0

@jensgram podría ser - o podría estar configurado para mostrar los resultados de las llamadas a funciones (a saber, 'LAST_INSERT_ID()'). No sé cómo funcionan los registros de consulta –

1

last_insert_id sólo funciona para AUTO_INCREMENT columnas. No funcionará si inserta un valor manualmente en la columna AUTO_INCREMENT.

La doctrina funcionará porque es como asignarle un NULL (aunque nunca específicamente lo escriba). Esto activa el incremento automático y proporciona un valor para last_insert_id().

He incluido un jpg aquí para que pueda verlo. ¡Espero eso ayude!

enter image description here

+0

Esto no explica cómo la doctrina realmente recupera el valor. No hay consulta recuperando last_insert_id. – ryeguy

+0

Esta respuesta no está relacionada con la pregunta. – prostynick

Cuestiones relacionadas