В вашем определении таблицы поле h_id
равно h_id serial NOT NULL
.Бит serial
означает, что для этого поля была создана последовательность, так что каждый раз, когда вы вставляете новую запись в эту таблицу, поле h_id
по умолчанию будет иметь значение nextval('jat.history_h_id_seq')
.
Когда поле настроено таким образом, в большинстве случаев вам никогда не следует вручную указывать это поле и значение в команде INSERT, потому что это означает, что nextval('jat.history_h_id_seq')
не будет вызываться и увеличиваться, что может вызвать проблемы, которые выВы испытываете.
Например, давайте создадим новую таблицу: CREATE TABLE t (id SERIAL PRIMARY KEY, txt TEXT);
.Последовательность с именем schema_name.t_id_seq
будет автоматически создана вместе с таблицей.Я также поместил первичный ключ в id
, так как это также PK вашей таблицы.
Теперь вставьте новую запись правильно: INSERT INTO t (txt) VALUES ('hello');
Это создаст запись, содержащую значения id: 1, txt: 'hello'
.Я вообще не указал id
, но он автоматически получил значение 1. Если я вставлю другую запись таким же образом, id
новой записи будет 2.
Вместо этого я будуневерно вставить новую запись: INSERT INTO t (id, txt) VALUES (2, 'bye');
.Это работает нормально, но я вручную установил значение id
, что означает, что последовательность не использовалась, поэтому ее «следующее значение» по-прежнему равно 2. Теперь, если я правильно вставлю другую запись: INSERT INTO t (txt) VALUES ('test');
, она не будет выполнена суникальная ошибка нарушения, потому что он пытается использовать nextval
значение последовательности (2) для id
, но запись с таким идентификатором уже существует, потому что я указал это поле вручную.
В любом случае этопроблема с вашими данными.И согласно запросам, которые вы выполнили, чтобы получить MAX(h_id)
из вашей таблицы и значение last_value
из вашей последовательности, у вас в таблице более высокие идентификаторы, чем у вашей последовательности, тогда как самый высокий идентификатор в вашей таблице должен быть таким жекак (или ниже) вашей последовательности last_value
.
Чтобы исправить это, сначала обновите последовательность до максимального идентификатора из вашей таблицы: SELECT SETVAL('jat.history_h_id_seq', (SELECT MAX(h_id) FROM jat.history));
Это обновит текущую вашу последовательностьзначение самого высокого идентификатора в вашей таблице, поэтому при следующем использовании последовательности следующий идентификатор (последний / текущий + 1) будет больше, чем что-либо в вашей таблице, поэтому не будет дубликатом.
И вторая часть - убедиться, что вы никогда не указали h_id
в любом операторе вставки.Просто позвольте ему автоматически получить следующее значение из последовательности.В противном случае вы снова столкнетесь с этой проблемой.