Solución:
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án nombres names_id_seq
.
Después de insertar en la tabla, puede llamar currval()
con ese nombre de secuencia:
postgres=> CREATE TABLE names in schema_name (id serial, name varchar(20));
CREATE TABLE
postgres=> insert into names (name) values ('Arthur Dent');
INSERT 0 1
postgres=> select currval('names_id_seq');
currval
---------
1
(1 row)
postgres=>
En lugar de codificar el nombre de la secuencia, también puede usar pg_get_serial_sequence()
en lugar de:
select currval(pg_get_serial_sequence('names', 'id'));
De esa manera, no necesita depender de la estrategia de nomenclatura que usa Postgres.
O si no desea usar el nombre de la secuencia en absoluto, use lastval()
Esto es directamente de 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:
SELECT last_value FROM your_sequence_name;
Utilice el enlace a SO para obtener más información.
Sin embargo, a partir de la documentación de Postgres, se indica claramente que
Es un error llamar a lastval si aún no se ha llamado a nextval en la sesión actual.
Entonces, supongo que, estrictamente hablando, para usar correctamente currval o last_value para una secuencia entre sesiones, ¿necesitaría hacer algo así?
SELECT setval('serial_id_seq',nextval('serial_id_seq')-1);
Suponiendo, por supuesto, que no tendrá un inserto o cualquier otra forma de usar el campo de serie en la sesión actual.
Necesitas llamar nextval
para esta secuencia en esta sesión antes currval
:
create sequence serial;
select nextval('serial');
nextval
---------
1
(1 row)
select currval('serial');
currval
---------
1
(1 row)
por lo que no puede encontrar la ‘última identificación insertada’ de la secuencia a menos que el insert
se realiza 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 tipo serial
creará automáticamente una secuencia y la usará para generar el valor predeterminado para la columna, por lo que insert
normalmente accede nextval
implícitamente:
create table my_table(id serial);
NOTICE: CREATE TABLE will create implicit sequence "my_table_id_seq" for
serial column "my_table.id"
d my_table
Table "stack.my_table"
Column | Type | Modifiers
--------+---------+-------------------------------------------------------
id | integer | not null default nextval('my_table_id_seq'::regclass)
insert into my_table default values;
select currval('my_table_id_seq');
currval
---------
1
(1 row)