Hay veces que realizamos operaciones de inserción que involucran valores autonuméricos y necesitamos averiguar el idetificador del último registro que hemos añadido para utilizarlo en verificaciones, o incluso en otras operaciones con la base de datos, como insertar registros hijos.
La función a utilizar en este caso sería last_insert_id(), a continuación muestro un ejemplo de su funcionamiento
He establecido un entorno de pruebas muy sencillo con un pequeño esquema que representa un sistema de autobuses y sus viajeros.
La tabla autobuses registraría las diferentes líneas entre dos
ciudades. Para identificar los autobuses se utiliza una columna
de tipo AUTO_INCREMENT que aumentará de valor automáticamente sin
que tengamos que especificarla. Al crear una columna de este
tipo, es obligatorio que se use en una clave, así que la usaremos
como clave primaria.
CREATE TABLE autobuses(
id_bus int not null AUTO_INCREMENT,
ciudad_origen text not null,
ciudad_destino text not null,
PRIMARY KEY(id_bus)
);
La tabla de viajeros registraría los viajeros que pueden utilizar
el servicio, se utiliza un identificador de viajero del mismo
tipo que el identificador del autobus
CREATE TABLE viajeros(
id_viajero int not null AUTO_INCREMENT,
nombre text not null,
apellidos text not null,
PRIMARY KEY(id_viajero)
);
Por último necesitamos una tabla que referencie los autobuses con
los viajeros en una fecha, es decir que controle las fechas y las
líneas que utiliza cada viajero.
CREATE TABLE autobuses_viajeros(
id_bus int not null,
id_viajero int not null,
fecha date not null
);
Damos de alta un autobús realizando una operación de inserción
(omitimos el campo de identificación del autobús porque se
rellena de forma automática con la columna de tipo
AUTO_INCREMENT)
mysql> insert into autobuses (ciudad_origen,
ciudad_destino)
VALUES ('Barcelona', 'Zaragoza');
Query OK, 1 row affected (0.02 sec)
Podemos recuperar el valor del último registro generado con
last_insert_id()
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
Podemos dar de alta viajeros insertándolos, cada vez que
insertemos un registro que involucra a una columna de tipo
AUTO_INCREMENT o autonumérica, el valor de last_insert_id()
varía, es decir que se genera cada vez que se llama a un
autonumérico a nivel de sesión.
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Juan', 'Pérez');
Query OK, 1 row affected (0.01 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Manuel', 'Fernández');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into viajeros (nombre,apellidos)
VALUES ('María', 'López');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 3 |
+------------------+
1 row in set (0.00 sec)
Debo aclarar también que el valor de last_insert_id() es
privado para la sesión que ejecuta las llamadas a columnas de
tipo AUTO_INCREMENT, nadie más excepto nuestra sesión tendrá
acceso al identificador de registro generado.
El valor recuperado por last_insert_id() se puede utilizar
normalmente donde prodría ir una expresión, por ejemplo una
sentencia de inserción del último viajero en una línea de bus
determinada.
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Rosa', 'Álvarez');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 4 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into autobuses_viajeros
(id_bus, id_viajero, fecha)
VALUES (1, last_insert_id(), now());
Query OK, 1 row affected (0.02 sec)
mysql> select * from autobuses_viajeros;
+--------+------------+------------+
| id_bus | id_viajero | fecha |
+--------+------------+------------+
| 1 | 4 | 2008-04-30 |
+--------+------------+------------+
1 row in set (0.00 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 4 |
+------------------+
1 row in set (0.00 sec)
En este caso podemos comprobar que se utiliza correctamente el
valor de last_insert_id() para la inserción en otra tabla y que
esa inserción en una tabla que no contiene valores AUTO_INCREMENT
no hace que el valor de last_insert_id() varíe.
Nota: La función now() devuelve la fecha y hora actuales, como el campo es de tipo date, solamente almacena la fecha.
Pero vamos a rizar un poco más el asunto, ¿qué ocurre cuándo se
utiliza last_insert_id() en un insert múltiple?, es decir, cuando
se insertan varios registros en una sola sentencia:
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Ramón', 'Sánchez'),('Sara','Hernández'),
('Julián','Martínez');
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 5 |
+------------------+
1 row in set (0.00 sec)
Mysql retornará el valor generado por el primer registro
insertado, pero no por el resto. Si hubieramos insertado los
3 viajeros en 3 inserts diferentes, hubieramos obtenido 5, 6 y 7
como valores para last_insert_id().
Espero haber aclarado un poco más sobre el funcionamiento de last_insert_id() con este caso práctico.