Después de tanto trabajar ya dimos con el arreglo de esta dificultad que algunos usuarios de nuestro sitio web tienen. Si tienes algún detalle que aportar no dudes en compartir tu información.
Solución:
los currval
devolverá el último valor generado para la secuencia dentro de la sesión actual. Entonces, si otra sesión genera un nuevo valor para la secuencia, aún puede recuperar el último valor generado por SU sesión, evitando errores.
Pero, para obtener el último valor generado en cualquier sesión, puede usar lo anterior:
SELECT last_value FROM your_sequence_name;
Tenga cuidado, si otra sesión usó el valor con una transacción no confirmada (o anulada) y usa este valor como referencia, es posible que obtenga un error. Incluso después de obtener este valor, es posible que ya esté desactualizado. Por lo general, la gente solo necesita la currval
o incluso el regreso de setval
.
Esto puede ser más simple de lo que piensas…
Mi objetivo es conseguir una primaria. key campo insertado automáticamente al insertar una nueva fila en la tabla.
Simplemente establezca el valor predeterminado de la columna:
ALTER TABLE tbl ALTER COLUMN tbl_id SET DEFAULT nextval('my_seq'::regclass);
O más simple aún, crea la tabla con un serial
tipo para primaria key para empezar:
CREATE TABLE tbl(
tbl_id serial PRIMARY KEY
,col1 txt
-- more columns
);
Crea una secuencia dedicada y establece el valor predeterminado para tbl_id automáticamente.
De esta manera tbl_id
se le asigna el siguiente valor de la secuencia adjunta automáticamente si no lo menciona en el INSERT
. Funciona con ningún sesión, concurrente o no.
INSERT INTO tbl(col1) VALUES ('foo');
Si quieres lo nuevo tbl_id
volver a hacer algo con él:
INSERT INTO tbl(col1) VALUES ('foo') RETURNING tbl_id;
Voy a dar una respuesta práctica para este asunto. Mi servidor de base de datos es utilizado por mis programas y mi terminal psql; así que hay varias sesiones. actualmente estoy en mi terminal psql:
fooserver=> select currval('fusion_id_seq');
ERROR: currval of sequence "fusion_id_seq" is not yet defined in this session
fooserver=> select nextval('fusion_id_seq');
nextval
---------
320032
(1 row)
fooserver=> select currval('fusion_id_seq');
currval
---------
320032
(1 row)
Parece que solo puede ver los valores en su propia sesión. Esto también afectará el curso de otra sesión. Esto probablemente esté relacionado con subprocesos múltiples del servidor para aislar diferentes sesiones. El contador (serie en psql) es un objeto compartido. En mi opinión, esta sesión debería poder obtener el valor actual del contador siempre que el contador esté correctamente bloqueado para garantizar que solo un único subproceso (sesión) pueda incrementarlo (operación atómica). Pero podría estar equivocado aquí (no soy un experto en escritores de servidores de bases de datos).
Si estás de acuerdo, puedes dejar una noticia acerca de qué le añadirías a esta crónica.