Actualización:Más tarde, respuesta más detallada:
Esto debería funcionar sin problemas:
CREATE OR REPLACE FUNCTION f_next_free(_seq regclass)
RETURNS integer AS
$func$
BEGIN
LOOP
PERFORM nextval(_seq);
EXIT WHEN NOT EXISTS (SELECT 1 FROM db.t1 WHERE id = lastval());
END LOOP;
RETURN lastval();
END
$func$ LANGUAGE plpgsql VOLATILE;
El ciclo busca el siguiente número de la secuencia dada hasta que se encuentra uno que aún no está en la tabla. Incluso debería ser seguro para uso concurrente , ya que todavía dependemos de una secuencia.
Use esta función en la columna predeterminada de la columna serial (reemplazando la predeterminada para las columnas seriales nextval('t1_id_seq'::regclass)
:
ALTER TABLE db.t1 ALTER COLUMN id
SET DEFAULT f_next_free('t1_id_seq'::regclass);
Esto funciona bien con pocas islas y muchas lagunas (que parece ser el caso según el ejemplo). Para hacer cumplir singularidad, agregue una restricción única (o clave principal) en la columna.