Baza : PostgreSQL
Keidy wstawiam jakis rekord to jak wyczaic ID ostatnio dodanego rekordu
czy jest na to jakas wbudowania funkcja z bazy ?
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");
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 ?
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.
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.
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 ?
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.
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.
@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.
wowo napisał(a)
hmm oidy to oidy ;-) są unikalne dla całego serwera postgresa
dopóki się im licznik nie "przekręci" ;-P
taaa misiekD zawsze czlowieka pocieszy :} ale
mam nadzieje ze ten licznik duzy jest raczej
raczej bardzo duży :-)
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.
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 1
Tym samym zupełnie bezużyteczna staje się funkcja currval.
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
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.
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. :-|