Możesz użyć CTE, aby pobrać wartość z sekwencji raz i używaj go wielokrotnie :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
CTE z poleceniem modyfikującym dane wymaga Postgresa 9.1 lub nowszego.
Jeśli nie masz pewności co do nazwy sekwencji, użyj pg_get_serial_sequence() zamiast tego:
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Jeśli nazwa tabeli „foo” może nie być unikalna we wszystkich schematach w bazie danych, zakwalifikuj ją według schematu. A jeśli pisownia jakiejkolwiek nazwy jest niestandardowa, musisz udzielić podwójnego cudzysłowu:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
Szybkie testy wskazały pomysł @Marka z lastval() może pracuj też:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
Możesz po prostu zostawić
idpoza zapytaniemserialkolumna zostanie przypisana automatycznie. Nie ma znaczenia. -
Nie powinno być warunku wyścigu między rzędami. Cytuję instrukcję:
currval
Zwróć wartość ostatnio uzyskaną przez nextval dla tej sekwencji w bieżącej sesji. (Błąd jest zgłaszany, jeśli nextval nigdy nie został wywołany dla tej sekwencji w tej sesji). Ponieważ zwraca to wartość lokalną sesji, daje przewidywalną odpowiedź, czy inne sesje wykonały nextval, czy nie. od bieżącego identyfikatora sesji.
Ta funkcja wymaga USAGE lub SELECT przywileje w sekwencji.
lastval
Zwróć wartość ostatnio zwróconą przez nextval w bieżącej sesji. Ta funkcja jest identyczna z currval , z wyjątkiem że zamiast brać nazwę sekwencji jako argument, odnosi się do której eversequence nextval został ostatnio zastosowany w bieżącej sesji. Wywołanie lastval jest błędem jeśli nextval nie został jeszcze wywołany w bieżącej sesji.
Ta funkcja wymaga USAGE lub SELECT uprawnienia do ostatnio używanej sekwencji.
Pogrubiony nacisk na moje.
Ale , jak skomentował @Bernard, mimo wszystko może się nie powieść:nie ma gwarancji, że domyślna wartość jest wypełniona (i nextval() wywołane w procesie) przed lastval() jest wywoływany, aby wypełnić drugą kolumnę ltree . Więc trzymaj się pierwszego rozwiązania i nextval() dla pewności.