PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Insérer dans postgres SQL

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.