55

我有一个 URL 表。他们包含

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

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

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

4

5 回答 5

85

这已经被问过很多次了。可以在这里找到一个可能的解决方案: 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/1109198/2873507

于 2012-06-21T09:58:52.393 回答
12

如果INSERTS很少见,我会避免这样做,因为它会在所有更新中NOT EXISTS (...)发出 a 。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.

于 2016-11-26T20:57:58.387 回答
7

我发现这篇文章在这种情况下更相关:

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)
于 2017-09-11T20:07:26.577 回答
3

首先它尝试插入。如果列上存在冲突,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();
于 2020-05-05T21:13:50.433 回答
1
create table urls (
      url_id serial primary key, 
      url text unique, 
      content text,
      last_analyzed timestamptz);

insert into urls(url) values('hello'),
   ('How'),('are'),
   ('you'),('doing');

通过创建过程,您还可以执行 upsert。

CREATE OR REPLACE PROCEDURE upsert_url(_url text) LANGUAGE plpgsql
as $$
BEGIN 
     INSERT INTO URLs (url) values (_url)
      ON CONFLICT (url) 
      DO UPDATE SET last_analyzed = NOW();
END 
$$;

通过调用程序对其进行测试。

call upsert_url('I am is ok');
call upsert_url('hello');
于 2021-12-07T07:34:31.330 回答