Postgresql,如果存在具有某些唯一值的行,则更新,否则插入

时间:2012-06-21 09:42:41

标签: postgresql triggers plpgsql

我有一个网址表。它们包含

(id int主键,  网址字符变化独特, 内容字符变化, 最后分析日期)。

我想创建触发器或某些东西(规则可能是),所以每次我从我的java程序插入时,如果存在具有这种URL的行,它会更新一些单行。否则它应该执行插入。

请你能在Postgresql中提供完整的代码吗?感谢。

4 个答案:

答案 0 :(得分:54)

这已被多次询问过。可以在这里找到可能的解决方案: https://stackoverflow.com/a/6527838/552671

此解决方案需要UPDATEINSERT

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);

使用Postgres 9.1,可以使用一个查询来执行此操作: https://stackoverflow.com/a/8702291/552671

答案 1 :(得分:5)

我发现this post在这种情况下更具相关性:

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)

答案 2 :(得分:4)

如果INSERTS很少见,我会避免执行NOT EXISTS (...),因为它会在所有更新中发出SELECT。相反,请看一下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'; 

这样Postgres最初会尝试UPDATE。如果没有行受到影响,它将回退到发出INSERT

答案 3 :(得分:2)

首先,它尝试插入。如果 & 列上存在冲突,则它将更新内容和last_analyzed字段。如果很少进行更新,这可能是更好的选择。

url