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

Rom*_*dev 31 postgresql triggers plpgsql

我有一个URL表.他们包含

(id int主键,url字符变化唯一,内容字符变化,最后分析日期).

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

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

Dav*_*ter 60

这已被问过很多次了.可以在此处找到可能的解决方案: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);
Run Code Online (Sandbox Code Playgroud)

使用Postgres 9.1,可以通过一个查询来完成:https: //stackoverflow.com/a/8702291/552671


Tah*_*afa 7

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

INSERT INTO URLs (url, content, last_analyzed)
VALUES
    (
        %(url)s,
        %(content)s,
        NOW()
    ) 
ON CONFLICT (url) 
DO
UPDATE
SET content=%(content)s, last_analyzed = NOW();
Run Code Online (Sandbox Code Playgroud)


dhr*_*tel 6

我发现这篇文章在这个场景中更相关:

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)
Run Code Online (Sandbox Code Playgroud)


chr*_*sen 5

如果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'; 
Run Code Online (Sandbox Code Playgroud)

这样Postgres将首先尝试做一个UPDATE。如果没有行受到影响,它将退回到发出一个INSERT