Ne fais pas ça ! JAMAIS ! N'y pensez même pas !
C'est FAUX solution peut sembler (ce n'est pas le cas) fonctionner pour vous :
INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');
MAIS , si quelqu'un essaie d'insérer en même temps que vous, vous obtiendrez tous les deux le même id
, ce qui entraînera un résultat invalide. Vous devriez vraiment utiliser une sequence
ou un mécanisme plus fiable (une table auxiliaire est courante lorsque vous ne pouvez pas avoir de trous dans la séquence, mais elle présente certains inconvénients [elle se verrouillera]). Vous pouvez même utiliser serial
type de données pour le rendre plus facile (il crée une séquence en dessous):
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', ...);
Si vous ne pouvez vraiment, vraiment, VRAIMENT pas créer et utiliser une séquence, vous pouvez faire comme ci-dessus, mais vous devrez gérer l'exception (en supposant que le id
champ est PK ou UK, et en utilisant une transaction de lecture validée), quelque chose comme ça (en 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;
Mais encore une fois, je vous recommande fortement de l'éviter :utilisez une séquence et soyez heureux... =D
De plus, je sais que c'est un exemple, mais utilisez une liste de colonnes explicite sur INSERT INTO
clause.