J'ai une petite table (~ 30 lignes) dans ma base de données Postgres 9.0 avec un champ d'ID entier (la clé primaire) qui contient actuellement des entiers séquentiels uniques commençant à 1, mais qui n'a pas été créé à l'aide du mot-clé 'serial'.
Comment puis-je modifier cette table de sorte qu'à partir de maintenant, les insertions dans cette table provoquent le comportement de ce champ comme s'il avait été créé avec 'serial' comme type?
postgresql
nicolaskruchten
la source
la source
SERIAL
pseudo-type est désormais hérité , supplanté par la nouvelleGENERATED … AS IDENTITY
fonctionnalité définie dans SQL: 2003 , dans Postgres 10 et versions ultérieures. Voir l' explication .Réponses:
Regardez les commandes suivantes (en particulier le bloc commenté).
la source
ALTER TABLE foo ADD PRIMARY KEY (a)
.ALTER TABLE foo OWNER TO current_user;
abord le faire .MAX(a)+1
à setval?SELECT MAX(a)+1 FROM foo; SELECT setval('foo_a_seq', 6);
Vous pouvez également utiliser
START WITH
pour démarrer une séquence à partir d'un point particulier, bien que setval accomplisse la même chose, comme dans la réponse d'Euler, par exemple,la source
TL; DR
Voici une version où vous n'avez pas besoin d'un humain pour lire une valeur et la saisir lui-même.
Une autre option serait d'utiliser le
Function
partage réutilisable à la fin de cette réponse.Une solution non interactive
Il suffit d'ajouter aux deux autres réponses, pour ceux d'entre nous qui ont besoin de
Sequence
créer ces s par un script non interactif , tout en corrigeant une base de données en direct par exemple.Autrement dit, lorsque vous ne voulez pas
SELECT
la valeur manuellement et tapez-la vous-même dans uneCREATE
instruction ultérieure .Bref, vous ne pouvez pas faire:
... puisque la
START [WITH]
clause inCREATE SEQUENCE
attend une valeur , pas une sous-requête.Mais
setval()
oui! Ainsi, ce qui suit est absolument parfait:S'il n'y a pas de données et que vous ne (voulez) pas le savoir, utilisez
coalesce()
pour définir la valeur par défaut:Cependant, avoir la valeur de séquence actuelle définie sur
0
est maladroit, voire illégal.L'utilisation de la forme à trois paramètres de
setval
serait plus appropriée:La définition du troisième paramètre optionnel de
setval
tofalse
empêchera le suivantnextval
d'avancer la séquence avant de renvoyer une valeur, et donc:- à partir de cette entrée dans la documentation
Sur une note non liée, vous pouvez également spécifier la colonne possédant
Sequence
directement avecCREATE
, vous n'avez pas à la modifier plus tard:En résumé:
Utilisant un
Function
Sinon, si vous prévoyez de le faire pour plusieurs colonnes, vous pouvez opter pour l'utilisation d'un fichier réel
Function
.Utilisez-le comme ceci:
la source
coalesce(max(a), 0))
cela ne fonctionnera pas la plupart du temps, car les identifiants commencent généralement à partir de 1. Une manière plus correcte seraitcoalesce(max(a), 1))
setval
fonction définit en fait uniquement la "dernière valeur utilisée" actuelle pour la séquence. La prochaine valeur disponible (la première à être réellement utilisée) sera une de plus! Utilisersetval(..., coalesce(max(a), 1))
sur une colonne vide la mettrait à "démarrer" avec2
(la prochaine valeur disponible), comme illustré dans la documentation .currval
ne devrait jamais être0
, même si cela ne serait pas reflété dans l'ensemble de données réel. En utilisant la forme à trois paramètres desetval
serait plus approprié:setval(..., coalesce(max(a), 0) + 1, false)
. Réponse mise à jour en conséquence!