[PostgreSQL] skad wziac ID ostatniej operacji INSERT

0

Baza : PostgreSQL
Keidy wstawiam jakis rekord to jak wyczaic ID ostatnio dodanego rekordu
czy jest na to jakas wbudowania funkcja z bazy ?

0

a masz nałożonmy jakiś klucz główny typu serial?

jeżeli tak to zrób

    select curval("nazwa_twojego_klucz_który_znajduje_się_w_sequencies");
0

tak mam klucz glowny typiu serial jako int4 zaraz wyproboje to zapytanie byloby extra gdyby zadzialalo.

Chcialbym wykluczyc taka ewentualnosc ze dwie osoby dodaja cos w tym samym czasie i teraz:
osoba A i osoba B otwieraja pole do dodawania jakiejs informacji
osoba A i osoba B dodaja w tym samym czasie jakies linijki do bazy
powiedzmy ze kazdda z osob dodaje po 1000 rekordow
czyli jesli jedna wcisnie DODAJ i druga wcisnie DODAJ
to czy istnieje szansa ze te wiersze sie dodaja naprzemian ?
czy jesli ktoras z osob zaczela dodawanie to druga czeka az ta jedna skonczy ?

gdyby jednak dzialo sie ze wiersze sa dodawane np na przemian ze moze sie zdarzyc
ze 3 wiersze sstem dospial od osoby B i 4 wiersze osoby A i znwou 2 wiersze osoby B
az tak do 2000 wierszy to czy to zapytanie powyzsze bedzie dzialac? czy to zwroci mi
ID ostatniej operacji INSERT ?

0

trzeba rozpatrzyć tutaj TRANSAKCYJNOŚĆ bazy danych.

dla przykładu w php będzie to takk (oczywiście pomijam kwestie nawiżania połączenia ;) )

     $zmienna = pg_query($connection, "insert bal bla bla; select curval('nazwa sekwencji')");

w tym wypadku nie ma możliwości żeby ci zwróciło coś innego.

0

Robi się to tak:

jak wstawisz insertem to wywołujesz funkcję php pg_last_oid() a nastepnie pobierasz serial, w ten sposob:

czyli:

$last_oid=pg_last_oid($result);
$query="SELECT id FROM tabela WHERE oid=$last_oid";

Oczywiście musisz mieć tabelę z OIDami.

0

o wlasnie musze wlaczyc OIDy czyli to sa unikalne indexy tak?
ta funkcja pg_last_oid(); to jest wbudowana w PostgreSQL`a ?
bo ja pytalem o czyste wywoalnie funkcji nie w php tylko tak zeby zwrocic to w samej konsoli bazy danych. czy musze sobie jakas funkcje sam zbudowac ?

p.s. nie wiem jak wlaczyc OID w danej tabeli jak to zrobic ?

0

hmm oidy to oidy ;-) są unikalne dla całego serwera postgresa, poczytaj o tym.
pg_last_oid() jest funkcja php, w postgresie tego nie ma. Tzn to jest chyba tak, że zapytanie insert zwraca ten oid, a ty sobie go tym po prostu pobierasz.

0
jmail napisał(a)
     $zmienna = pg_query($connection, "insert bal bla bla; select curval('nazwa sekwencji')");

w tym wypadku nie ma możliwości żeby ci zwróciło coś innego.

W tym też nie:

     pg_query($connection, "insert bal bla bla;");
     pg_query("select currval('nazwa sekwencji')");

Wystarczy poczytać FAQ PostgreSQL'a:

4.11.3) Doesn't currval() lead to a race condition with other users?

No. currval() returns the current value assigned by your session, not by all sessions.

Szukanie nie boli.

0

@Elmo: to nie zadziała. Jeśli dopiero co połączyłbyś się z bazą i chciał pobrać currval-em tą wartość, to ci nie zwróci, dopiero po pierwszym wstawieniu (czyli po pierwszym wykorzystaniu sekwencji z seriala) będziesz mógł dostać obecną wartość, dlatego lepiej to zrobić wykorzystując OIDy.

0
wowo napisał(a)

hmm oidy to oidy ;-) są unikalne dla całego serwera postgresa

dopóki się im licznik nie "przekręci" ;-P

0

taaa misiekD zawsze czlowieka pocieszy :} ale
mam nadzieje ze ten licznik duzy jest raczej

0

raczej bardzo duży :-)

0
Elmo napisał(a)
jmail napisał(a)
     $zmienna = pg_query($connection, "insert bal bla bla; select curval('nazwa sekwencji')");

w tym wypadku nie ma możliwości żeby ci zwróciło coś innego.

W tym też nie:

     pg_query($connection, "insert bal bla bla;");
     pg_query("select currval('nazwa sekwencji')");

Wystarczy poczytać FAQ PostgreSQL'a:

4.11.3) Doesn't currval() lead to a race condition with other users?

No. currval() returns the current value assigned by your session, not by all sessions.

Szukanie nie boli.

A jestem w stanie ci udowodnić że jednak nie zadziała. każde pg_query będzie wykonywane jako osobna transakcja. inaczej nie miałoby to sensu. i teraz jak ktoś ci sie wbije pomiędzy te dwie transakcje to będziesz leżał i kwiczał bo dostaniesz zupełnie inne id.

0
wowo napisał(a)

@Elmo: to nie zadziała. Jeśli dopiero co połączyłbyś się z bazą i chciał pobrać currval-em tą wartość, to ci nie zwróci, dopiero po pierwszym wstawieniu (czyli po pierwszym wykorzystaniu sekwencji z seriala) będziesz mógł dostać obecną wartość, dlatego lepiej to zrobić wykorzystując OIDy.

string pg_last_oid ( resource result )

Po parametrze widać, że tutaj też musiałeś mieć wykonane zapytanie.

jmail napisał(a)

A jestem w stanie ci udowodnić że jednak nie zadziała.

Z chęcią bym to zobaczył, bo z dokumentacji mi wychodzi, że nie pownieneś być w stanie (sam z tej właściwości korzystam i wcale nie byłoby dla mnie dobrym jakby się okazało, że masz rację :/).

jmail napisał(a)

każde pg_query będzie wykonywane jako osobna transakcja.

Transakcje mnie nie obchodzą. W FAQ i dokumentacji jest użyte pojęcie sesja (!=transakcja), który dla mnie jest równoznaczne z połączeniem (zmiana sesji = rozłączenie i połączenie).

jmail napisał(a)

inaczej nie miałoby to sensu.

"to"? To znaczy co? Bo IMHO w Twoim podejściu currval ma średnio sens.
Według Ciebie currval miałby zwaracać ostatnią wartość sekwencji (niezależnie przez kogo aktualizowaną)?
To nie ma sensu. Uzasadnienie:
Sekwencje albo rosną albo maleją. Oznacza to, że aby wybrać rekord z ostatnią (największą/najmniejszą) wartością wystarczy:select * from table order by seq_col desc/asc limit 1Tym samym zupełnie bezużyteczna staje się funkcja currval.

0
Elmo napisał(a)
string pg_last_oid ( resource result )

Po parametrze widać, że tutaj też musiałeś mieć wykonane zapytanie.

jako parametr podajesz uchwyt do wykonanego zapytania

0
masterO napisał(a)

taaa misiekD zawsze czlowieka pocieszy :} ale
mam nadzieje ze ten licznik duzy jest raczej

cytat z FAQu postgresa napisał(a)

OIDy są przechowywane jako cztero-bajtowe liczby całkowite i skończą się po osiągnięciu czterech miliardów. Nikt jak dotąd nie zgłosił aby coś takiego się stalo, ale mamy zamiar pozbyć się tego ograniczenia zanim ktoś to zgłosi.

0
wowo (niezalogowany) napisał(a)
Elmo napisał(a)
string pg_last_oid ( resource result )

Po parametrze widać, że tutaj też musiałeś mieć wykonane zapytanie.

jako parametr podajesz uchwyt do wykonanego zapytania

Tzn. to to odpowiedź do mnie? Bo specjalnie nie wiem co Twoja wypowiedź wnosi - jest jedynie powtórzeniem tego co ja napisałem. :-|

1 użytkowników online, w tym zalogowanych: 0, gości: 1