我有一个 URL 表。他们包含
(id int 主键,url 字符变化唯一,内容字符变化,最后分析日期)。
我想创建触发器或其他东西(可能是规则),所以每次我从我的 java 程序中插入时,如果存在具有此类 URL 的行,它会更新一些单行。否则它应该执行插入。
请问,你能在 Postgresql 中提供完整的代码吗?谢谢。
我有一个 URL 表。他们包含
(id int 主键,url 字符变化唯一,内容字符变化,最后分析日期)。
我想创建触发器或其他东西(可能是规则),所以每次我从我的 java 程序中插入时,如果存在具有此类 URL 的行,它会更新一些单行。否则它应该执行插入。
请问,你能在 Postgresql 中提供完整的代码吗?谢谢。
这已经被问过很多次了。可以在这里找到一个可能的解决方案: https ://stackoverflow.com/a/6527838/552671
此解决方案同时需要UPDATE
和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);
使用 Postgres 9.1,可以通过一个查询来完成: https ://stackoverflow.com/a/1109198/2873507
如果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
.
我发现这篇文章在这种情况下更相关:
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)
首先它尝试插入。如果列上存在冲突,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();
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');