PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Valeur de référence de la colonne série dans une autre colonne lors du même INSERT

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, le serial 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 si nextval 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 non nextval depuis la session en cours.

Cette fonction nécessite USAGE ou SELECT 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équence nextval a été appliqué le plus récemment dans la session en cours. C'est une erreur d'appeler lastval si nextval n'a pas encore été appelé dans la session en cours.

Cette fonction nécessite USAGE ou SELECT 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.