Mise à jour :Plus tard, réponse plus détaillée :
Cela devrait fonctionner correctement :
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;
La boucle récupère le numéro suivant de la séquence donnée jusqu'à ce qu'il en trouve un qui n'est pas encore dans la table. Devrait même être sûr pour une utilisation simultanée , puisque nous nous appuyons toujours sur une séquence.
Utilisez cette fonction dans la colonne par défaut de la colonne série (en remplaçant la valeur par défaut pour les colonnes série nextval('t1_id_seq'::regclass)
:
ALTER TABLE db.t1 ALTER COLUMN id
SET DEFAULT f_next_free('t1_id_seq'::regclass);
Cela fonctionne bien avec peu d'îlots et de nombreuses lacunes (ce qui semble être le cas selon l'exemple). Pour appliquer unicité, ajoutez une contrainte unique (ou clé primaire) sur la colonne.