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ć
id
poza zapytaniemserial
kolumna 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.