Tengo una pequeña tabla (~ 30 filas) en mi base de datos de Postgres 9.0 con un campo de ID de número entero (la clave principal) que actualmente contiene enteros secuenciales únicos que comienzan en 1, pero que no se creó con la palabra clave 'serial'.
¿Cómo puedo alterar esta tabla para que de ahora en adelante las inserciones en esta tabla hagan que este campo se comporte como si se hubiera creado con 'serial' como tipo?
postgresql
nicolaskruchten
fuente
fuente
SERIAL
pseudo-tipo ahora es heredado , reemplazado por la nuevaGENERATED … AS IDENTITY
característica definida en SQL: 2003 , en Postgres 10 y posteriores. Ver explicación .Respuestas:
Observe los siguientes comandos (especialmente el bloque comentado).
fuente
ALTER TABLE foo ADD PRIMARY KEY (a)
.ALTER TABLE foo OWNER TO current_user;
primero.MAX(a)+1
ponerte en setval?SELECT MAX(a)+1 FROM foo; SELECT setval('foo_a_seq', 6);
También puede usar
START WITH
para comenzar una secuencia desde un punto en particular, aunque setval logra lo mismo, como en la respuesta de Euler, por ejemplo,fuente
TL; DR
Aquí hay una versión en la que no necesita un ser humano para leer un valor y escribirlo ellos mismos.
Otra opción sería emplear el
Function
compartido reutilizable al final de esta respuesta.Una solución no interactiva
Solo agregando a las otras dos respuestas, para aquellos de nosotros que necesitamos que estos mensajes de correo electrónico sean
Sequence
creados por un script no interactivo , mientras parcheamos una base de datos en vivo, por ejemplo.Es decir, cuando no desea
SELECT
el valor manualmente y lo escribe usted mismo en unaCREATE
declaración posterior .En resumen, se puede no hacer:
... ya que la
START [WITH]
cláusula enCREATE SEQUENCE
espera un valor , no una subconsulta.¡Sin embargo, lo
setval()
hace! Por lo tanto, lo siguiente está absolutamente bien:Si no hay datos y usted no (quiere) saberlo, use
coalesce()
para establecer el valor predeterminado:Sin embargo, tener el valor de secuencia actual establecido en
0
es torpe, si no ilegal.Usar la forma de tres parámetros de
setval
sería más apropiado:Establecer el tercer parámetro opcional de
setval
tofalse
evitará que el siguientenextval
avance en la secuencia antes de devolver un valor, y así:- de esta entrada en la documentación
En una nota no relacionada, también puede especificar la columna a la que pertenece
Sequence
directamenteCREATE
, no tiene que modificarla más tarde:En resumen:
Usando un
Function
Alternativamente, si planea hacer esto para varias columnas, puede optar por usar un archivo
Function
.Úselo así:
fuente
coalesce(max(a), 0))
que no funcionará la mayor parte del tiempo, ya que los identificadores generalmente comienzan desde 1. La forma más correcta seríacoalesce(max(a), 1))
setval
realidad, la función solo establece el "último valor utilizado" actual para la secuencia. ¡El siguiente valor disponible (el primero que se utilizará realmente) será uno más! El usosetval(..., coalesce(max(a), 1))
en una columna vacía lo configuraría para "comenzar" con2
(el siguiente valor disponible), como se ilustra en la documentación .currval
nunca debería ser así0
, incluso si no se reflejaría en el conjunto de datos real. Usando la forma de tres parámetros desetval
sería más apropiado:setval(..., coalesce(max(a), 0) + 1, false)
. ¡Respuesta actualizada en consecuencia!