Можете да използвате 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
е приложен за последно в текущата сесия. Грешка е да се извикаlastval
ifnextval
все още не е извикан в текущата сесия.Тази функция изисква
USAGE
илиSELECT
привилегия върху последната използвана последователност.
Удебелен акцент мой.
Но , както коментира @Bernard, все пак може да се провали:няма гаранция, че стойността по подразбиране е попълнена (и nextval()
извикани в процеса) преди lastval()
се извиква, за да запълни 2-ра колона ltree
. Затова се придържайте към първото решение и nextval()
за да съм сигурен.