Можете да използвате CTE, за да извлечете стойността от последователността веднъж и го използвайте многократно :
WITH cte AS (
SELECT nextval('foo_id_seq') AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM cte;
CTE с команда за модифициране на данни изисква Postgres 9.1 или по-нова версия.
Ако не сте сигурни за името на последователността, използвайтеpg_get_serial_sequence() вместо това:
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
Ако името на таблицата "foo" може да не е уникално във всички схеми в DB, квалифицирайте го по схема. И ако изписването на някое име е нестандартно, трябва да цитирате:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
Бързите тестове показаха идеята на @Mark с lastval() може би работа също:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
-
Можете просто да оставите
idизвън заявкатаserialколоната ще бъде присвоена автоматично. Няма разлика. -
Не трябва да има условие за състезание между редовете. Цитирам ръководството:
currvalВърнете стойността, получена последно от
nextvalза тази последователност в текущата сесия. (Грешка се съобщава, акоnextvalникога не е бил извикан за тази последователност в тази сесия.) Тъй като това връща локална стойност на сесията, то дава предвидим отговор дали други сесии са изпълнилиnextvalтъй като текущата сесия го направи.Тази функция изисква
USAGEилиSELECTпривилегия върху последователността.
lastvalВърнете стойността, върната последно от
nextvalв текущата сесия. Тази функция е идентична наcurrval, освенто че вместо да приеме името на последователността като аргумент, то се отнася към коя последователностnextvalе приложен за последно в текущата сесия. Грешка е да се извикаlastvalifnextvalвсе още не е извикан в текущата сесия.Тази функция изисква
USAGEилиSELECTпривилегия върху последната използвана последователност.
Удебелен акцент мой.
Но , както коментира @Bernard, все пак може да се провали:няма гаранция, че стойността по подразбиране е попълнена (и nextval() извикани в процеса) преди lastval() се извиква, за да запълни 2-ра колона ltree . Затова се придържайте към първото решение и nextval() за да съм сигурен.