Nie rób tego! KAŻDY ! Nawet o tym nie myśl!
To NIEPRAWIDŁOWE rozwiązanie może wydawać się (nie działa) dla Ciebie:
INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
ALE , jeśli ktoś spróbuje wstawić w tym samym czasie co Ty, oboje otrzymacie ten sam id
, co spowoduje nieprawidłowy wynik. Naprawdę powinieneś użyć sequence
lub jakiś bardziej niezawodny mechanizm (stół pomocniczy jest powszechny, gdy nie możesz mieć dziur w sekwencji, ale ma pewne wady [zablokuje się]). Możesz nawet użyć serial
typ danych, aby to ułatwić (tworzy sekwencję poniżej):
CREATE TABLE lists(id serial, col2 text, col3 text, ...);
-- If you don't specify "id", it will autogenerate for you:
INSERT INTO lists(col2, col3, ...) VALUES('KO','SPH', ...);
-- You can also specify using DEFAULT (the same as above):
INSERT INTO lists(id, col2, col3, ...) VALUES(DEFAULT, 'KO','SPH', ...);
Jeśli naprawdę, naprawdę, NAPRAWDĘ, nie możesz stworzyć i używać sekwencji, możesz zrobić to jak powyżej, ale będziesz musiał obsłużyć wyjątek (zakładając, że id
pole to PK lub UK, i używając odczytanej zatwierdzonej transakcji), coś takiego (w PL/pgSQL):
DECLARE
inserted bool = false;
BEGIN
WHILE NOT inserted LOOP;
BEGIN
INSERT INTO lists
VALUES ((SELECT coalesce(max(id),0)+1 FROM lists),'KO','SPH', '5');
inserted = true;
EXCEPTION
WHEN unique_violation THEN
NULL; -- do nothing, just try again
END;
END LOOP;
END;
Ale znowu, gorąco polecam, aby tego uniknąć:użyj sekwencji i bądź szczęśliwy... =D
Wiem też, że to przykład, ale użyj jawnej listy kolumn na INSERT INTO
klauzula.