Tengo una mesa:
CREATE TABLE names (id serial, name varchar(20))
Quiero la "última identificación insertada" de esa tabla, sin usar RETURNING id
en insertar. Parece que hay una función CURRVAL()
, pero no entiendo cómo usarla.
He intentado con:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
pero ninguno de ellos funciona. ¿Cómo puedo usar currval()
para obtener la última identificación insertada?
postgresql
sequence
Jonas
fuente
fuente
currval()
definitivamente no se desaconseja.Respuestas:
Si crea una columna como
serial
PostgreSQL crea automáticamente una secuencia para eso.El nombre de la secuencia se genera automáticamente y siempre es tablename_columnname_seq, en su caso la secuencia será nombres
names_id_seq
.Después de insertar en la tabla, puede llamar
currval()
con ese nombre de secuencia:En lugar de codificar el nombre de la secuencia, también puede usar
pg_get_serial_sequence()
en su lugar:De esa manera, no necesita confiar en la estrategia de nombres que utiliza Postgres.
O si no desea utilizar el nombre de la secuencia, use
lastval()
fuente
currval()
en una configuración multiusuario. Por ejemplo, en un servidor web.currval()
es "local" a su conexión actual. Por lo tanto, no hay problema para usarlo en un entorno multiusuario. Ese es todo el propósito de una secuencia.Esto es directamente desde Stack Overflow
Como lo señalaron @a_horse_with_no_name y @Jack Douglas, currval solo funciona con la sesión actual. Entonces, si está de acuerdo con el hecho de que el resultado podría verse afectado por una transacción no confirmada de otra sesión, y aún desea algo que funcione en todas las sesiones, puede usar esto:
Use el enlace a SO para obtener más información.
Sin embargo, de la documentación de Postgres , se afirma claramente que
Entonces, supongo que, estrictamente hablando, para usar correctamente currval o last_value para una secuencia entre sesiones, ¿debería hacer algo así?
Suponiendo, por supuesto, que no tendrá una inserción ni ninguna otra forma de usar el campo serial en la sesión actual.
fuente
nextval()
, debe configurar manualmente la secuencia para que coincida con el número de registros de dispositivos que insertó con las ID codificadas. Además, la forma de resolver el problema de que currval () / lastval () no esté disponible pre-nextval es simplementeSELECT
en la secuencia directamente.Usted necesita llamar
nextval
a esta secuencia en esta sesión antescurrval
:por lo que no puede encontrar la 'última identificación insertada' de la secuencia a menos que
insert
se realice en la misma sesión (una transacción puede revertirse pero la secuencia no)como se señala en la respuesta de a_horse,
create table
con una columna de tiposerial
creará automáticamente una secuencia y la usará para generar el valor predeterminado para la columna, por lo queinsert
normalmente se accedenextval
implícitamente a:fuente
Entonces, hay algunos problemas con estos diversos métodos:
Currval solo obtiene el último valor generado en la sesión actual, lo cual es excelente si no tiene nada más que genere valores, pero en los casos en que podría llamar a un desencadenante y / o avanzar la secuencia más de una vez en la transacción actual, es No va a devolver el valor correcto. Eso no es un problema para el 99% de las personas, pero es algo que uno debe tener en cuenta.
La mejor manera de obtener el identificador único asignado después de una operación de inserción es usar la cláusula RETURNING. El siguiente ejemplo supone que la columna vinculada a la secuencia se llama "id":
Tenga en cuenta que la utilidad de la cláusula RETURNING va mucho más allá de simplemente obtener la secuencia, ya que también:
Devuelve los valores que se estaban eliminando:
eliminar de la tabla A donde id> 100 regresando *
Devuelve las filas modificadas después de una ACTUALIZACIÓN:
actualizar la tabla A conjunto X = 'y' donde blah = 'blech' regresando *
Use el resultado de una eliminación para una actualización:
CON A como (eliminar * de la tabla A como ID de retorno) actualización B establecer eliminado = verdadero donde id en (seleccionar id de A);
fuente
RETURNING
cláusula, pero no hay nada de malo en hacer que los beneficios de usarlo sean más claros para los demás.Tuve que ejecutar una consulta a pesar de usar SQLALchemy porque no tuve éxito al usar currval.
Este fue un matraz de Python + proyecto postgresql.
fuente
Si desea obtener el valor de las secuencias sin haber llamado
nextval()
y sin tener que modificar la secuencia, preparé una función PL / pgSQL para manejarla: encuentre el valor de todas las secuencias de la base de datosfuente
Necesita
GRANT
usar en el esquema, así:y
fuente
currval()
función para que sea un poco más relevante para este hilo?En PostgreSQL 11.2 puede tratar la secuencia como una tabla que parece:
Ejemplo si tiene una secuencia llamada: 'names_id_seq'
Eso debería darle la última identificación insertada (4 en este caso), lo que significa que el valor actual (o el valor que debe usarse para la siguiente identificación) debe ser 5.
fuente
Las diferentes versiones de PostgreSQL pueden tener diferentes funciones para obtener la identificación de secuencia actual o siguiente.
Primero, debes conocer la versión de tus Postgres. Utilizando select version (); para obtener la versión
En PostgreSQL 8.2.15, obtiene la identificación de secuencia actual utilizando
select last_value from schemaName.sequence_name
.Si la declaración anterior no funciona, puede usar
select currval('schemaName.sequence_name');
fuente