Función NEXTVAL en PostgreSQL
NEXTVAL()
tiende a avanzar un objeto a otro valor y devolverlo. Los ‘OBJETOS DE SECUENCIA’ son solo tablas de una sola fila creadas a partir de ‘SECUENCIAS’ en PostgreSQL.
La función NEXTVAL()
se define en FUNCIONES DE MANIPULACIÓN DE SECUENCIA
.
nextval ( regclass ) ? bigint
REGCLASS
se refiere al SEQUENCE OBJECT
, y esta función tiende a devolver BIGINT
. Ahora veamos algunas implementaciones posibles de esta función NEXTVAL()
y cómo podemos usarla.
Ejemplo Práctico de NEXTVAL()
en PostgreSQL
Uno de los usos de los IDENTIFICADORES DE SECUENCIA
en PostgreSQL es cómo se pueden usar para obtener valores de identificador de fila únicos. Puede leer más sobre ellos en CREAR SECUENCIA
URL.
Haremos un seguimiento del uso dado anteriormente y luego intentaremos implementar un sistema que pueda usar efectivamente la función NEXTVAL()
. Arrancaremos PostgreSQL y crearemos una tabla simple llamada RANDOM_GEN
(abreviatura de generador aleatorio).
CREATE TABLE RANDOM_GENE(
val INT PRIMARY KEY
);
Hemos utilizado un VALOR
simple como CLAVE PRINCIPAL
en nuestra tabla, ya que será único y aleatorio. Ahora sigamos adelante y agreguemos algunos datos a esta tabla.
Por supuesto, el VAL
debe ser RANDOM
para usar el GENERADOR DE SECUENCIA
en PostgreSQL. Nuestro tutorial utilizará un GENERADOR EN SERIE
con valores incrementales para obtener VALOR ÚNICO
.
CREATE SEQUENCE serial_num;
Y para utilizar los valores de este GENERADOR DE SECUENCIAS
, podemos consultar una operación SELECCIONAR
de esta tabla.
SELECT * from SERIAL_NUM;
Pero hay un problema. Si llamamos repetidamente a esta operación SELECCIONAR
, tendemos a obtener el mismo valor del GENERADOR DE SECUENCIA
.
Entonces, si tuviéramos que INSERTAR
valores de esta SECUENCIA
en nuestra tabla sin probar, habríamos terminado con valores duplicados.
Y aquí es donde entra la función NEXTVAL()
. Podemos avanzar y avanzar el valor de este GENERADOR
y luego ejecutar la operación SELECCIONAR
para obtener los valores ascendentes.
Entonces podemos escribir:
SELECT * from NEXTVAL('serial_num');
Y esto devolverá la salida de la siguiente manera, digamos, 5 iteraciones.
Producción :
Iter VAL
1 1
2 2
3 3
4 4
5 5
Entonces NEXTVAL()
, como vimos, tiende a aumentar el GENERADOR DE SECUENCIA
y avanzarlo. Entonces, cada vez que se llama a NEXTVAL()
para la SECUENCIA
pasada en su argumento, podemos imaginar que la SECUENCIA
se apunte al siguiente valor ascendente.
Por lo tanto, ahora podemos llamar algo de la siguiente manera para una operación INSERT
en nuestra tabla RANDOM_GEN
.
INSERT INTO RANDOM_GENE values (NEXTVAL('SERIAL_NUM')), (NEXTVAL('SERIAL_NUM')), (NEXTVAL('SERIAL_NUM'));
Nuestra tabla ahora se verá de la siguiente manera.
Producción :
val
1 1
2 2
3 3
Otra forma sencilla de lograr esto solo para la columna VALUE
sería definir NEXTVAL()
justo en la instrucción CREATE TABLE
. Podemos escribir una consulta de la siguiente manera.
CREATE TABLE RANDOM_GENE(
val INT primary key default NEXTVAL('SERIAL_NUM')
);
Hemos utilizado DEFAULT
para definir el comportamiento predeterminado de esta columna VAL
que obtiene valores del GENERADOR DE SECUENCIA
. Por supuesto, lo anterior es inútil sin una columna secundaria, así que agreguemos una columna USER_NAME
para definir los USUARIOS
que reciben los valores RANDOM_GEN
.
CREATE TABLE RANDOM_GENE(
val INT primary key default NEXTVAL('SERIAL_NUM'),
name TEXT
);
Ahora podemos escribir una instrucción INSERTAR
de la siguiente manera.
INSERT into RANDOM_GENE (name) values ('John'), ('Marta'), ('Alex');
Esto INSERTARÁ
los nombres dados en la consulta a nuestra tabla con los respectivos valores obtenidos en orden ascendente de nuestro GENERADOR DE SECUENCIAS
. Si tendemos ahora a mirar la tabla, quedaría de la siguiente manera.
val name
1 "John"
2 "Marta"
3 "Alex"
Por lo tanto, ahora hemos entendido completamente cómo funciona NEXTVAL()
. Por ahora, veamos el funcionamiento de NEXTVAL()
en diferentes entornos.
NEXTVAL()
en diferentes entornos y circunstancias en PostgreSQL
El uso de NEXTVAL()
tiende a incrementar el GENERADOR DE SECUENCIA
cada vez que se llama. Por lo tanto, no tenemos que preocuparnos por los duplicados en este caso.
Una vez que se llama a NEXTVAL()
, el GENERATOR
avanza y calcula el siguiente valor. Cualquier otra consulta que se ejecute simultáneamente que llame a NEXTVAL()
para la misma SECUENCIA
obtendrá el valor único y completamente diferente del generador.
Por lo tanto, es eficiente y seguro usar NEXTVAL()
para múltiples transacciones y procesos que pueden estar ejecutando consultas en un servidor de Postgres.
Brechas y diferencias de valor de NEXTVAL()
en PostgreSQL
Un problema común que se encuentra en NEXTVAL()
es la implementación estricta del avance. Una vez que la SECUENCIA
avanza a los nuevos valores, es muy poco probable que regrese o incluso verifique si se ha utilizado un valor anterior o no.
Entonces, en caso de que tenga una tabla con una columna de valor ÚNICA
y un NOMBRE
, y de alguna manera el NOMBRE
que está tratando de INSERTAR
ya está presente en la tabla, puede obtener un error de violación. NEXTVAL()
ya habría sido llamado en ese escenario.
Y la SECUENCIA
avanzó a un valor, pero la violación impide la INSERCIÓN
. Entonces, la próxima vez que se llame a INSERT
, NEXTVAL()
avanzará una vez más, y el valor anterior se omitirá por completo.
Lo mismo puede decirse de las operaciones ON CONFLICT
o aquellas que no puedan ejecutarse correctamente. En el ejemplo que se muestra a continuación, use lo siguiente para llamar a un INSERTAR
en la columna de la tabla NOMBRE
.
name TEXT unique
Y luego, “INSERTAR” datos en nuestra tabla con un nombre duplicado intencional para ALEX
con una consulta de la siguiente manera.
INSERT into RANDOM_GENE (name) values ('John'), ('Marta'), ('Alex'), ('Alex'), ('Mathew') on conflict (name) do nothing;
Hemos puesto EN CONFLICTO
para evitar el error de violación duplicada y verificar nuestra tabla para el VALOR
. La tabla ahora se ve de la siguiente manera.
val name
1 "John"
2 "Marta"
3 "Alex"
5 "Mathew"
Puedes ver como no hay valor número 4 para la columna VAL
. Y eso se debe a que la inserción duplicada de ALEX
hizo avanzar el GENERADOR DE SECUENCIA
pero no se INSERTÓ
.
De ahí que para el nombre MATHEW
, el valor ya estaba en 4, que luego avanzó a 5 para su INSERCIÓN
.
Así que ahora esperamos que hayas entendido completamente cómo funciona NEXTVAL()
y puedas implementarlo como quieras.
Hello, I am Bilal, a research enthusiast who tends to break and make code from scratch. I dwell deep into the latest issues faced by the developer community and provide answers and different solutions. Apart from that, I am just another normal developer with a laptop, a mug of coffee, some biscuits and a thick spectacle!
GitHub