【问题标题】:PostgreSql INSERT is trying to use existing primary keysPostgreSql INSERT 正在尝试使用现有的主键
【发布时间】:2018-11-01 07:48:59
【问题描述】:

我在使用 Postgres 表时遇到了一个特殊问题。当我尝试执行一个简单的INSERT 时,它返回一个错误 - duplicate key value violates unique constraint

首先,这是表的架构:

CREATE TABLE app.guardians
(
  guardian_id serial NOT NULL,
  first_name character varying NOT NULL,
  middle_name character varying,
  last_name character varying NOT NULL,
  id_number character varying NOT NULL,
  telephone character varying,
  email character varying,
  creation_date timestamp without time zone NOT NULL DEFAULT now(),
  created_by integer,
  active boolean NOT NULL DEFAULT true,
  occupation character varying,
  address character varying,
  marital_status character varying,
  modified_date timestamp without time zone,
  modified_by integer,
  CONSTRAINT "PK_guardian_id" PRIMARY KEY (guardian_id ),
  CONSTRAINT "U_id_number" UNIQUE (id_number )
)
WITH (
  OIDS=FALSE
);
ALTER TABLE app.guardians
  OWNER TO postgres;

该表有 400 行。现在假设我尝试执行这个简单的INSERT

INSERT INTO app.guardians(first_name, last_name, id_number) VALUES('This', 'Fails', '123456');

我得到错误:

ERROR:  duplicate key value violates unique constraint "PK_guardian_id"
DETAIL:  Key (guardian_id)=(2) already exists.

如果我再次尝试运行相同的查询,错误消息的详细信息将是:

DETAIL:  Key (guardian_id)=(3) already exists.

DETAIL:  Key (guardian_id)=(4) already exists.

递增直到它到达一个不存在的guardian_id

这张特定的桌子上可能出了什么问题,如何纠正?我认为这可能与之前使用cascade 删除表并重新输入数据有关,但我不确定这个理论。

【问题讨论】:

  • 尝试重启你的序列alter sequence "PK_guardian_id" start with (select max(quardian_id) + 1 from app.guardians)
  • 谢谢。这实际上对我有用。您可以将其发布为答案,以便我将其标记为答案。
  • 我很高兴该评论对​​您有所帮助:) 我已将其发布为答案

标签: postgresql postgresql-9.1 cascade insert-into


【解决方案1】:

这个错误的原因是你有错误的序列next_val。当您手动插入具有自动增量的字段时会发生这种情况

所以,你必须改变你的序列 next_val

alter sequence "PK_guardian_id"
start with (
   select max(quardian_id) + 1 
   from app.guardians
)

注意:

为避免阻塞从同一序列中获取数字的并发事务,ALTER SEQUENCE 对序列生成参数的影响永远不会回滚;这些更改立即生效且不可逆。但是,OWNED BY、OWNER TO、RENAME TO 和 SET SCHEMA 子句会导致可以回滚的普通目录更新。

ALTER SEQUENCE 不会立即影响具有预分配(缓存)序列值的后端中的 nextval 结果,而不是当前结果。他们将在注意到更改的序列生成参数之前用完所有缓存的值。当前后端将立即受到影响。

文档: https://www.postgresql.org/docs/9.6/static/sql-altersequence.html

【讨论】:

  • 嗨!我遇到了类似的问题,但是当我尝试运行此查询时,我得到了ERROR: "PK_guardian_id" is not a sequence。我查看了表信息,发现 id 列默认为nextval('guardian_id_seq'::regclass),因此我将查询更改为alter sequence "guardian_id_seq" start with (select max(quardian_id) + 1 from app.guardians)。它向我显示序列更新成功。但是当我再次尝试插入时,发生了同样的错误......
  • 默认 Postgres 使用公共模式来查找表。在您的情况下,序列放置在应用程序架构中,因此您将表放置在应用程序架构中,所以是的,您必须手动编写架构
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-07
  • 2023-03-10
  • 2021-08-20
  • 2017-11-30
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多