Vous pouvez utiliser un CTE pour récupérer la valeur de la séquence une fois et l'utiliser à plusieurs reprises :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
Le CTE avec une commande de modification de données nécessite Postgres 9.1 ou une version ultérieure.
Si vous n'êtes pas sûr du nom de la séquence, utilisez pg_get_serial_sequence()
à la place :
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Si le nom de table "foo" n'est peut-être pas unique sur tous les schémas de la base de données, qualifiez-le de schéma. Et si l'orthographe d'un nom n'est pas standard, vous devez mettre entre guillemets :
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
Des tests rapides ont indiqué l'idée de @Mark avec lastval()
pourrait travailler aussi :
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
Vous pouvez simplement laisser
id
hors de la requête, leserial
colonne sera attribuée automatiquement. Cela ne fait aucune différence. -
Il ne devrait pas y avoir de condition de concurrence entre les lignes. Je cite le manuel :
currval
Renvoie la valeur la plus récemment obtenue par
nextval
pour cette séquence dans la session en cours. (Une erreur est signalée sinextval
n'a jamais été appelé pour cette séquence dans cette session.) Parce que cela renvoie une valeur locale à la session, il donne une réponse prévisible, que d'autres sessions aient exécuté ou nonnextval
depuis la session en cours.Cette fonction nécessite
USAGE
ouSELECT
privilège sur la séquence.
lastval
Renvoie la valeur la plus récemment renvoyée par
nextval
dans la session en cours. Cette fonction est identique àcurrval
, sauf qu'au lieu de prendre le nom de la séquence comme argument, il se réfère à la séquencenextval
a été appliqué le plus récemment dans la session en cours. C'est une erreur d'appelerlastval
sinextval
n'a pas encore été appelé dans la session en cours.Cette fonction nécessite
USAGE
ouSELECT
privilège sur la dernière séquence utilisée.
J'insiste sur moi.
Mais , comme l'a commenté @Bernard, cela peut échouer après tout :il n'y a aucune garantie que la valeur par défaut soit remplie (et nextval()
appelé dans le processus) avant lastval()
est appelé pour remplir la 2ème colonne ltree
. Alors restez avec la première solution et nextval()
pour être sûr.