Postgres altera manualmente la secuencia


189

Estoy tratando de establecer una secuencia a un valor específico.

SELECT setval('payments_id_seq'), 21, true

Esto da un error:

ERROR: function setval(unknown) does not exist

¿Usar ALTER SEQUENCEtampoco parece funcionar?

ALTER SEQUENCE payments_id_seq LASTVALUE 22

¿Cómo se puede hacer esto?

Ref: https://www.postgresql.org/docs/current/static/functions-sequence.html


44
Parece que setval()tiene al menos dos argumentos.

Respuestas:


262

Los paréntesis están fuera de lugar:

SELECT setval('payments_id_seq', 21, true);  # next value will be 22

De lo contrario, está llamando setvalcon un solo argumento, mientras que requiere dos o tres.


2
¿Qué significa el último argumento "verdadero"?
inafalcao

15
truesignifica que el siguiente valor será el número proporcionado + 1, en este caso 22. falsesignifica que el siguiente valor sería el número proporcionado, o 21. Por defecto, setval se comportará como si truese hubiera elegido. Más detalles: postgresql.org/docs/9.6/static/functions-sequence.html
Tom Mertz el

1
Una ventaja de la select setvalsintaxis alter sequencees que puede usar consultas anidadas en ella, por ejemplo, para select max(id) from payments.
mariotomo

187

Esta sintaxis no es válida en ninguna versión de PostgreSQL:

ALTER SEQUENCE payments_id_seq LASTVALUE 22

Esto funcionaría:

ALTER SEQUENCE payments_id_seq RESTART WITH 22;

y es equivalente a:

SELECT setval('payments_id_seq', 22, FALSE);

Más en el manual actual para ALTER SEQUENCEy funciones de secuencia .

Tenga en cuenta que setval()espera (regclass, bigint)o (regclass, bigint, boolean). En el ejemplo anterior, estoy proporcionando literales sin tipo . Eso tambien funciona. Pero si alimenta las variables escritas a la función, puede necesitar conversiones de tipo explícitas para satisfacer la resolución del tipo de función. Me gusta:

SELECT setval(my_text_variable::regclass, my_other_variable::bigint, FALSE);

Para operaciones repetidas puede interesarle:

ALTER SEQUENCE payments_id_seq START WITH 22; -- set default
ALTER SEQUENCE payments_id_seq RESTART;       -- without value

START [WITH]almacena un RESTARTnúmero predeterminado , que se utiliza para RESTARTllamadas posteriores sin valor. Necesita Postgres 8.4 o posterior para la última parte.


44
ALTER SEQUENCE [sequence] RESTART WITH (SELECT MAX(col) from table);no funciona, mientras SELECT setval('sequence', (SELECT (MAX(col) from table), TRUE);que funciona. Me sale un error de sintaxis. (Postgres 9.4)
NuclearPeon

1
No se permiten subconsultas en un comando DDL ("comando de utilidad"). Ver: stackoverflow.com/a/36025963/939860
Erwin Brandstetter

1
@MitalPritmani: Es posible que necesite tipos de yeso. Considere agregar las instrucciones anteriores.
Erwin Brandstetter

1
@NuclearPeon Creo que quieres decir que de lo SELECT setval('sequence', (SELECT MAX(col) from table), TRUE);contrario tus padres no se alinean.
Dland

1
@dland: Aparte: equivalente más corto y más rápido: SELECT setval('seq', max(col)) FROM tbl;ver: stackoverflow.com/a/23390399/939860
Erwin Brandstetter

33

Utilizar select setval('payments_id_seq', 21, true);

setval contiene 3 parámetros:

  • El primer parámetro es sequence_name
  • El segundo parámetro es Siguiente nextval
  • El tercer parámetro es opcional.

El uso de verdadero o falso en el tercer parámetro de setval es el siguiente:

SELECT setval('payments_id_seq', 21);           // Next nextval will return 22
SELECT setval('payments_id_seq', 21, true);     // Same as above 
SELECT setval('payments_id_seq', 21, false);    // Next nextval will return 21

La mejor manera de evitar la codificación rígida del nombre de secuencia, el siguiente valor de secuencia y manejar correctamente la tabla de columnas vacía, puede usar la siguiente manera:

SELECT setval(pg_get_serial_sequence('table_name', 'id'), coalesce(max(id), 0)+1 , false) FROM table_name;

donde table_namees el nombre de la mesa, ides el primary keyde la mesa


¡Gracias! La última expresión es exactamente lo que estaba buscando. Me permite reservar los valores de secuencia para luego insertarlos por lotes.
Timur


0

No intento cambiar la secuencia a través de setval. Pero usando ALTERme emitieron cómo escribir el nombre de secuencia correctamente. Y esto solo funciona para mí:

  1. Verifique el nombre de secuencia requerido usando SELECT * FROM information_schema.sequences;

  2. ALTER SEQUENCE public."table_name_Id_seq" restart {number};

    En mi caso fue ALTER SEQUENCE public."Services_Id_seq" restart 8;

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.