En PostgreSQL, ¿cómo puedo insertar la última identificación en una tabla?
En MS SQL hay SCOPE_IDENTITY ().
Por favor no me aconsejen usar algo como esto:
select max(id) from table
postgresql
insert
lastinsertid
Anton
fuente
fuente
Respuestas:
(
tl;dr
: goto opción 3: INSERTAR con RETORNO)Recuerde que en postgresql no hay un concepto de "id" para las tablas, solo secuencias (que normalmente se usan, pero no necesariamente, como valores predeterminados para las claves primarias sustitutas, con el pseudotipo SERIAL ).
Si está interesado en obtener la identificación de una fila recién insertada, hay varias formas:
Opción 1:
CURRVAL(<sequence name>);
.Por ejemplo:
El nombre de la secuencia debe ser conocido, es realmente arbitrario; En este ejemplo, suponemos que la tabla
persons
tiene unaid
columna creada con elSERIAL
pseudotipo. Para evitar confiar en esto y sentirse más limpio, puede usar en su lugarpg_get_serial_sequence
:Advertencia:
currval()
solo funciona después de unINSERT
(que se ha ejecutadonextval()
), en la misma sesión .Opcion 2:
LASTVAL();
Esto es similar al anterior, solo que no necesita especificar el nombre de la secuencia: busca la secuencia modificada más reciente (siempre dentro de su sesión, la misma advertencia que la anterior).
Ambos
CURRVAL
yLASTVAL
son totalmente concurrentes seguros. El comportamiento de la secuencia en PG está diseñado para que una sesión diferente no interfiera, por lo que no hay riesgo de condiciones de carrera (si otra sesión inserta otra fila entre mi INSERT y mi SELECT, aún obtengo mi valor correcto).Sin embargo, tienen un problema potencial sutil. Si la base de datos tiene algún DISPARADOR (o REGLA) que, al insertarlo en la
persons
tabla, hace algunas inserciones adicionales en otras tablas ... entoncesLASTVAL
probablemente nos dará el valor incorrecto. El problema puede suceder inclusoCURRVAL
si las inserciones adicionales se realizan en la mismapersons
tabla (esto es mucho menos habitual, pero el riesgo aún existe).Opción 3:
INSERT
conRETURNING
Esta es la forma más limpia, eficiente y segura de obtener la identificación. No tiene ninguno de los riesgos de lo anterior.
Inconvenientes? Casi ninguno: es posible que deba modificar la forma en que llama a su instrucción INSERT (en el peor de los casos, quizás su capa API o DB no espera que un INSERT devuelva un valor); no es SQL estándar (a quién le importa); está disponible desde Postgresql 8.2 (diciembre de 2006 ...)
Conclusión: si puede, vaya a la opción 3. En otro lugar, prefiera 1.
Nota: todos estos métodos son inútiles si tiene la intención de obtener la última identificación insertada globalmente (no necesariamente por su sesión). Para esto, debe recurrir a
SELECT max(id) FROM table
(por supuesto, esto no leerá inserciones no confirmadas de otras transacciones).Por el contrario, nunca debe utilizar
SELECT max(id) FROM table
una de las 3 opciones anteriores, para obtener la identificación que acaba de generar suINSERT
declaración, porque (aparte del rendimiento) esto no es concurrentemente seguro: entre ustedINSERT
y suSELECT
otra sesión podría haber insertado otro registro.fuente
SELECT max(id)
desafortunadamente, tampoco hace el trabajo tan pronto como comienza a eliminar filas.1,2,3,4,5
y elimina las filas 4 y 5, la última ID insertada sigue siendo 5, peromax()
devuelve 3.RETURNING id;
para insertar esto en otra tabla sería bienvenida!RETURNING id
dentro de un script SQL alimentado a lapsql
herramienta de línea de comando?Consulte la cláusula RETURNING de la declaración INSERT . Básicamente, INSERT funciona como una consulta y le devuelve el valor que se insertó.
fuente
insert into names (firstname, lastname) values ('john', 'smith') returning id;
entonces simplemente genera la identificación como si se ejecutaraselect id from names where id=$lastid
directamente. Si desea guardar el retorno en una variable aa , entonces,insert into names (firstname, lastname) values ('john', 'smith') returning id into other_variable;
si la declaración que contiene el retorno es la última declaración en una función ,returning
la función en su conjunto devuelve el ID que se está editando.puede usar la cláusula RETURNING en la instrucción INSERT, como lo siguiente
fuente
La respuesta de Leonbloy es bastante completa. Solo agregaría el caso especial en el que uno necesita obtener el último valor insertado dentro de una función PL / pgSQL donde la OPCIÓN 3 no se ajusta exactamente.
Por ejemplo, si tenemos las siguientes tablas:
Si necesitamos insertar un registro de cliente, debemos referirnos a un registro de persona. Pero supongamos que queremos diseñar una función PL / pgSQL que inserte un nuevo registro en el cliente pero que también se encargue de insertar el nuevo registro de persona. Para eso, debemos usar una ligera variación de la OPCIÓN 3 de leonbloy:
Tenga en cuenta que hay dos cláusulas INTO. Por lo tanto, la función PL / pgSQL se definiría como:
Ahora podemos insertar los nuevos datos usando:
o
Y obtenemos la identificación recién creada.
fuente
Para aquellos que necesitan obtener el registro de todos los datos, pueden agregar
hasta el final de su consulta para obtener todos los objetos, incluida la identificación.
fuente
Ver el siguiente ejemplo
Luego, para obtener la última identificación insertada, use esto para la tabla "user" seq nombre de columna "id"
fuente
Debe proporcionar el nombre de la tabla y el nombre de la columna, por supuesto.
Esto será para la sesión / conexión actual http://www.postgresql.org/docs/8.3/static/functions-sequence.html
fuente
Prueba esto:
Si esto devuelve 1 (o lo que sea el valor inicial de su secuencia), restablezca la secuencia nuevamente al valor original, pasando el indicador falso:
De otra manera,
Esto restaurará el valor de secuencia al estado original y "setval" regresará con el valor de secuencia que está buscando.
fuente
Postgres tiene un mecanismo incorporado para el mismo, que en la misma consulta devuelve la identificación o lo que quiera que devuelva la consulta. Aquí hay un ejemplo. Considere que tiene una tabla creada que tiene 2 columnas column1 y column2 y desea que se devuelva column1 después de cada inserción.
fuente
Tuve este problema con Java y Postgres. Lo arreglé actualizando una nueva versión de Connector-J.
postgresql-9.2-1002.jdbc4.jar
https://jdbc.postgresql.org/download.html : Versión 42.2.12
https://jdbc.postgresql.org/download/postgresql-42.2.12.jar
fuente