Postgresql 将CSV导入Postgres:更新&;同时插入

Postgresql 将CSV导入Postgres:更新&;同时插入,postgresql,csv,postgresql-9.6,Postgresql,Csv,Postgresql 9.6,因此,我对Postgresql相当陌生,开始使用它,在Postgres9.6上使用pgadmin4测试一些东西 问题是: 我有一个表:test(id,text) 在这个表中,我有10行数据。 现在我想导入一个CSV,它有12行更新测试表。前10行的一些文本已更改,我想从CSV中插入另外2行 我知道您可以截断表中的所有数据,然后再次从CSV导入所有数据,但这不是一个好方法。我想更新现有数据并用一个查询插入新数据 我已经找到了一个函数,可以通过使用临时表来解决这个问题。这将正确更新现有行,但不会插入

因此,我对Postgresql相当陌生,开始使用它,在Postgres9.6上使用pgadmin4测试一些东西

问题是:

我有一个表:test(id,text)

在这个表中,我有10行数据。 现在我想导入一个CSV,它有12行更新测试表。前10行的一些文本已更改,我想从CSV中插入另外2行

我知道您可以截断表中的所有数据,然后再次从CSV导入所有数据,但这不是一个好方法。我想更新现有数据并用一个查询插入新数据

我已经找到了一个函数,可以通过使用临时表来解决这个问题。这将正确更新现有行,但不会插入另外两行

CREATE OR REPLACE FUNCTION upsert_test(integer,varchar) RETURNS VOID AS $$
DECLARE
BEGIN
    UPDATE test
SET id = tmp_table.id,
text = tmp_table.text
FROM tmp_table
WHERE test.id = tmp_table.id;
IF NOT FOUND THEN
INSERT INTO test(id,text) values 
(tmp_table.id,tmp_table.text);
END IF;
END;
$$ Language 'plpgsql';

DO $$ BEGIN
PERFORM upsert_test(id,text) FROM test;
END $$;

那么,我需要更改什么才能使插入也起作用呢?

假设您在
id
列上有一个主约束或唯一约束,您可以用一条语句来完成,无需函数:

insert into test (id, text)
select id, text
from tmp_table
on conflict (id) 
  do update set text = excluded.text;

假设在
id
列上有一个主约束或唯一约束,则只需一条语句即可实现,无需函数:

insert into test (id, text)
select id, text
from tmp_table
on conflict (id) 
  do update set text = excluded.text;

是的,我先尝试了,但我总是得到错误:一个subquery@StackAsk:然后您使用了不同的查询。回答中的问题不会导致那个错误哦,是的,我的错。很好。非常感谢。是的,我先尝试了,但我总是得到错误:一个subquery@StackAsk:然后您使用了不同的查询。回答中的问题不会导致那个错误哦,是的,我的错。很好。非常感谢。不相关,但是:语言名称是一个标识符。不要将其放在单引号中使用:
language plpgsql
Unrelated,但是:语言名称是一个标识符。不要将其放在单引号中使用:
language plpgsql