Mam stolik:
CREATE TABLE names (id serial, name varchar(20))
Chcę „ostatni wstawiony identyfikator” z tej tabeli, bez użycia RETURNING id
wstawiania. Wygląda na to, że jest jakaś funkcja CURRVAL()
, ale nie rozumiem, jak jej używać.
Próbowałem z:
SELECT CURRVAL() AS id FROM names_id_seq
SELECT CURRVAL('names_id_seq')
SELECT CURRVAL('names_id_seq'::regclass)
ale żaden z nich nie działa. Jak mogę użyć, currval()
aby uzyskać ostatni wstawiony identyfikator?
postgresql
sequence
Jonas
źródło
źródło
currval()
zdecydowanie nie jest odradzane.Odpowiedzi:
Jeśli utworzysz kolumnę, ponieważ
serial
PostgreSQL automatycznie utworzy sekwencję dla tego.Nazwa sekwencji jest generowana automatycznie i zawsze jest tablename_columnname_seq, w twoim przypadku sekwencją będą nazwy
names_id_seq
.Po wstawieniu do tabeli możesz wywołać
currval()
tę nazwę sekwencji:Zamiast na stałe wpisywać nazwę sekwencji, możesz również użyć
pg_get_serial_sequence()
:W ten sposób nie musisz polegać na strategii nazewnictwa używanej przez Postgres.
Lub jeśli nie chcesz w ogóle używać nazwy sekwencji, użyj
lastval()
źródło
currval()
w konfiguracji dla wielu użytkowników. Np. Na serwerze internetowym.currval()
jest „lokalny” dla bieżącego połączenia. Nie ma więc problemu z użyciem go w środowisku wielu użytkowników. To jest cały cel sekwencji.Jest to prosto z Przepełnienia stosu
Jak zauważyli @a_horse_w_nazwie i @Jack Douglas, currval działa tylko z bieżącą sesją. Jeśli więc zgadzasz się z faktem, że na wynik może mieć wpływ niezaangażowana transakcja innej sesji, a nadal chcesz czegoś, co będzie działać między sesjami, możesz użyć tego:
Aby uzyskać więcej informacji, skorzystaj z łącza do SO.
Z dokumentacji PostgreSQL chociaż, to jest wyraźnie powiedziane, że
Myślę więc, że mówiąc ściśle, aby właściwie użyć currval lub last_value dla sekwencji między sesjami, musisz zrobić coś takiego?
Zakładając oczywiście, że nie będziesz mieć wstawki ani żadnego innego sposobu używania pola szeregowego w bieżącej sesji.
źródło
nextval()
, musisz ręcznie ustawić sekwencję, aby dopasować liczbę wstawionych rekordów urządzeń z zakodowanymi identyfikatorami. Ponadto sposobem rozwiązania problemu niedostępności currval () / lastval () przed-nextval jest po prostuSELECT
bezpośrednio na sekwencji.Musisz zadzwonić
nextval
po tę sekwencję w tej sesji przedcurrval
:więc nie można znaleźć „ostatniego wstawionego identyfikatora” z sekwencji, chyba że
insert
zostanie to zrobione w tej samej sesji (transakcja może zostać wycofana, ale sekwencja nie zostanie)jak wskazano w odpowiedzi konia,
create table
kolumna typuserial
automatycznie utworzy sekwencję i użyje jej do wygenerowania domyślnej wartości dla kolumny, więcinsert
normalnie uzyskuje dostępnextval
pośredni:źródło
Istnieją więc problemy z tymi różnymi metodami:
Currval pobiera tylko ostatnią wartość wygenerowaną w bieżącej sesji - co jest świetne, jeśli nie masz żadnych innych wartości generujących, ale w przypadkach, w których możesz wywołać wyzwalacz i / lub ustawić sekwencję więcej niż raz w bieżącej transakcji, nie zwróci prawidłowej wartości. To nie jest problem dla 99% ludzi, ale należy to wziąć pod uwagę.
Najlepszym sposobem na przypisanie unikalnego identyfikatora po operacji wstawienia jest użycie klauzuli RETURNING. Poniższy przykład zakłada, że kolumna powiązana z sekwencją nosi nazwę „id”:
Zauważ, że użyteczność klauzuli RETURNING wykracza daleko poza samo uzyskanie sekwencji, ponieważ:
Zwróć wartości, które zostały usunięte:
usuń z tabeli A, gdzie zwracany jest identyfikator> 100 *
Zwróć zmodyfikowane wiersze po aktualizacji:
aktualizacja tabeli Zestaw X = „y”, gdzie blah = „blech” powraca *
Użyj wyniku usunięcia do aktualizacji:
Z A jako (usuń * z tabeli A jako zwracany identyfikator) aktualizacja B zestaw usunięty = prawda gdzie id w (wybierz identyfikator z A);
źródło
RETURNING
klauzuli - ale nie ma nic złego w tym, że korzyści płynące z korzystania z niej będą jaśniejsze dla innych.Musiałem wykonać zapytanie pomimo użycia SQLALchemy, ponieważ nie udało mi się użyć currval.
To był projekt kolby pytona + postgresql.
źródło
Jeśli chcesz uzyskać wartość sekwencji bez wywołania
nextval()
i bez konieczności modyfikowania sekwencji, rzuciłem razem funkcję PL / pgSQL do obsługi: Znajdź wartość wszystkich sekwencji bazy danychźródło
Musisz
GRANT
użyć na schemacie, tak jak to:i
źródło
currval()
funkcji, aby uczynić ją bardziej odpowiednią dla tego wątku?W PostgreSQL 11.2 sekwencję można traktować jak tabelę:
Przykład, jeśli masz sekwencję o nazwie: „names_id_seq”
To powinno dać ci ostatni wstawiony identyfikator (w tym przypadku 4), co oznacza, że bieżąca wartość (lub wartość, która powinna być użyta dla id dalej) powinna wynosić 5.
źródło
Różne wersje PostgreSQL mogą mieć różne funkcje, aby uzyskać identyfikator bieżącej lub następnej sekwencji.
Najpierw musisz znać wersję swojego Postgresa. Korzystanie z wyboru wersji (); aby uzyskać wersję.
W PostgreSQL 8.2.15 otrzymujesz bieżący identyfikator sekwencji za pomocą
select last_value from schemaName.sequence_name
.Jeśli powyższe oświadczenie nie działa, możesz użyć
select currval('schemaName.sequence_name');
źródło