PostgreSql INSERT пытается использовать существующие первичные ключи - PullRequest
0 голосов
/ 01 ноября 2018

У меня возникла специфическая проблема с таблицей 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 и данные были введены заново, но я не уверен в этой теории.

1 Ответ

0 голосов
/ 01 ноября 2018

Причиной этой ошибки является неправильная последовательность 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

...