web-dev-qa-db-fra.com

Postgresql, mettre à jour s'il existe une ligne avec une valeur unique, sinon insérer

J'ai un tableau d'URL. Ils contiennent

(clé int int primaire, caractère url variant unique, caractère variant selon le contenu, dernière date analysée).

Je veux créer un déclencheur ou quelque chose (la règle peut être), donc chaque fois que je fais une insertion à partir de mon programme Java, il met à jour une seule ligne si une ligne avec une telle URL existe. Sinon, il devrait effectuer un Insérer.

Veuillez fournir un code complet dans Postgresql. Merci.

31
Roman Lebedev

Cela a été demandé à plusieurs reprises. Une solution possible peut être trouvée ici: https://stackoverflow.com/a/6527838/552671

Cette solution nécessite à la fois un UPDATE et INSERT.

UPDATE table SET field='C', field2='Z' WHERE id=3;
INSERT INTO table (id, field, field2)
       SELECT 3, 'C', 'Z'
       WHERE NOT EXISTS (SELECT 1 FROM table WHERE id=3);

Avec Postgres 9.1, il est possible de le faire avec une seule requête: https://stackoverflow.com/a/1109198/2873507

57
Dave Halter

J'ai trouvé ce message plus pertinent dans ce scénario:

WITH upsert AS (
     UPDATE spider_count SET tally=tally+1 
     WHERE date='today' AND spider='Googlebot' 
     RETURNING *
)
INSERT INTO spider_count (spider, tally) 
SELECT 'Googlebot', 1 
WHERE NOT EXISTS (SELECT * FROM upsert)
6
dhruvpatel

Si INSERTS sont rares, j'éviterais de faire une NOT EXISTS (...) car elle émet une SELECT sur toutes les mises à jour. Au lieu de cela, jetez un œil à la réponse wildpeaks: https://dba.stackexchange.com/questions/5815/how-can-i-insert-if-key-not-exist-with-postgresql

CREATE OR REPLACE FUNCTION upsert_tableName(arg1 type, arg2 type) RETURNS VOID AS $$ 
    DECLARE 
    BEGIN 
        UPDATE tableName SET col1 = value WHERE colX = arg1 and colY = arg2; 
        IF NOT FOUND THEN 
        INSERT INTO tableName values (value, arg1, arg2); 
        END IF; 
    END; 
    $$ LANGUAGE 'plpgsql'; 

De cette façon, Postgres essaiera initialement de faire un UPDATE. Si aucune ligne n'est affectée, cela revient à émettre un INSERT.

4
chribsen