PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Inserisci in Postgres SQL

Non farlo! MAI ! Non pensare nemmeno di farlo!

Questo SBAGLIATO la soluzione potrebbe sembrare (non) funzionare per te:

INSERT INTO lists VALUES ((SELECT max(id)+1 FROM lists),'KO','SPH', '5');

MA , se qualcuno tentasse di inserire contemporaneamente a te, entrambi otterreste lo stesso id , che causerà un risultato non valido. Dovresti davvero usare una sequence o qualche meccanismo più affidabile (una tabella ausiliaria è comune quando non puoi avere buchi nella sequenza, ma ha alcuni inconvenienti [si bloccherà]). Puoi persino usare serial tipo di dati per renderlo più semplice (crea una sequenza sotto):

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 davvero, davvero, DAVVERO, non puoi creare e utilizzare una sequenza, puoi fare come sopra, ma dovrai gestire l'eccezione (assumendo l'id il campo è PK o UK e usando una transazione con commit di lettura), qualcosa del genere (in 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;

Ma ancora una volta, ti consiglio vivamente di evitarlo:usa una sequenza e sii felice... =D

Inoltre, so che è un esempio, ma usa l'elenco di colonne esplicite su INSERT INTO clausola.