Não faça isso! NUNCA ! Nem pense em fazer isso!
Isso ERRADO solução pode parecer (não) funcionar para você:
INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
MAS , se alguém tentar inserir ao mesmo tempo que você, ambos obterão o mesmo
id
, o que causará um resultado inválido. Você realmente deveria usar uma sequence
ou algum mecanismo mais confiável (uma mesa auxiliar é comum quando você não pode ter furos na sequência, mas tem algumas desvantagens [ela trava]). Você pode até usar serial
tipo de dados para facilitar (ele cria uma sequência abaixo):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', ...);
Se você realmente não pode criar e usar uma sequência, você pode fazer como acima, mas terá que lidar com a exceção (assumindo o
id
campo é PK ou UK, e usando uma transação de leitura confirmada), algo assim (em 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;
Mas, novamente, eu recomendo que você evite isso:use uma sequência e seja feliz... =D
Além disso, eu sei que é um exemplo, mas use a lista de colunas explícitas em
INSERT INTO
cláusula.