为什么在PostgreSQL中执行COPY时不更新序列?

时间:2012-02-01 06:32:08

标签: sql postgresql

我在PostgreSQL中使用COPY语句插入批量记录。我意识到,序列ID没有得到更新,当我尝试稍后插入记录时,它会抛出重复的序列ID。我应该在执行COPY后手动更新序列号以获取记录数量吗?执行COPY时是否有解决方案,只需递增序列变量,即表的主键字段?请澄清一下。提前谢谢!

例如,如果我插入200条记录,COPY表示良好,我的表格会显示所有记录。当我稍后手动插入记录时,它会显示duplicate sequence ID error。这很好地暗示它在COPYing期间没有增加序列ID,因为在正常INSERTing期间工作正常。而不是指示序列id设置最大记录数,是否有任何机制来教育COPY命令在批量COPYing选项期间增加序列ID?

3 个答案:

答案 0 :(得分:22)

你问:

  

我应该在执行COPY后手动更新序列号以获取记录数吗?

是的,您应该documented here

  

在COPY FROM后更新序列值:

| BEGIN;
| COPY distributors FROM 'input_file';
| SELECT setval('serial', max(id)) FROM distributors;
| END;

你写道:

  

它在COPYing期间没有增加序列ID,因为在正常INSERTing期间工作正常

但事实并非如此! :)执行常规INSERT时,通常不为SEQUENCE支持的主键指定显式值。如果你这样做,你会遇到与现在相同的问题:

postgres=> create table uh_oh (id serial not null primary key, data char(1));
NOTICE:  CREATE TABLE will create implicit sequence "uh_oh_id_seq" for serial column "uh_oh.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "uh_oh_pkey" for table "uh_oh"
CREATE TABLE
postgres=> insert into uh_oh (id, data) values (1, 'x');
INSERT 0 1
postgres=> insert into uh_oh (data) values ('a');
ERROR:  duplicate key value violates unique constraint "uh_oh_pkey"
DETAIL:  Key (id)=(1) already exists.

当然,您的COPY命令正在提供显式的id值,就像上面的示例INSERT一样。

答案 1 :(得分:6)

我意识到这有点老了,但也许有人可能仍在寻找答案。

正如其他人所说的COPY以与INSERT类似的方式工作,因此对于插入具有序列的表,您根本就不提及序列字段,而是为您处理。对于COPY,它以同样的方式工作。但它不是COPY要求表中的所有字段都出现在文本文件中吗?正确的答案是NO,但它没有,但这是默认行为。

要复制并退出序列,请执行以下操作:

COPY $YOURSCHEMA.$YOURTABLE(col1,col2,col3,col4) FROM '$your_input_file' DELIMITER ',' CSV HEADER;

之后无需手动更新架构,它可以按预期工作,在我的测试中速度也一样快。

答案 2 :(得分:3)

您可以复制到姐妹表,然后insert into mytable select * from sister - 这会增加序列。

如果您加载的数据具有id字段,请不要为插入选择它:insert into mytable (col1, col2, col3) select col1, col2, col3 from sister