sql >> Base de Datos >  >> RDS >> PostgreSQL

Insertar en postgres SQL

¡No hagas eso! NUNCA ! ¡Ni siquiera pienses en hacer eso!

Esto INCORRECTO la solución puede parecer (no funciona) para usted:

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

PERO , si alguien intenta insertar al mismo tiempo que usted, ambos obtendrán el mismo id , lo que provocará un resultado no válido. Realmente deberías usar una sequence o algún mecanismo más confiable (una mesa auxiliar es común cuando no puedes tener agujeros en la secuencia, pero tiene algunos inconvenientes [se bloqueará]). Incluso puedes usar serial tipo de datos para hacerlo más fácil (crea una secuencia debajo):

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 realmente, realmente, REALMENTE, no puede crear y usar una secuencia, puede hacer lo anterior, pero tendrá que manejar la excepción (suponiendo que el id el campo es PK o UK, y usa una transacción de lectura confirmada), algo así (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;

Pero de nuevo, te recomiendo que lo evites:usa una secuencia y sé feliz... =D

Además, sé que es un ejemplo, pero use una lista de columnas explícitas en INSERT INTO cláusula.