Ошибка повторяющегося ключа при использовании INSERT DEFAULT

Я получаю повторяющуюся ошибку ключа, DB2 SQL Error: SQLCODE=-803, SQLSTATE=23505, когда пытаюсь ВСТАВИТЬ записи. Первичный ключ — это один столбец, INTEGER 4, Generated, и это первый столбец.

вставка выглядит так: ВСТАВИТЬ В СХЕМУ.ТАБЛИЦА1 значения (ПО УМОЛЧАНИЮ, ?, ?, ...)

Насколько я понимаю, использование значения DEFAULT просто позволит DB2 автоматически сгенерировать ключ во время вставки, чего я и хочу. Это работает большую часть времени, но иногда/случайно я получаю ошибку дублирующего ключа. Мысли?

В частности, я работаю с DB2 9.7.0.3, используя Scriptella для копирования набора записей из одной базы данных в другую. Иногда я могу обработать кучу без проблем, в других случаях я получаю сообщение об ошибке сразу же, в других случаях после 2 записей, 20 записей, 30 записей и т. д. Не похоже, что это закономерность, и это не одно и то же записывать каждый раз. Если я изменю данные, чтобы скопировать 1 запись вместо группы, иногда я получаю ошибку один раз, тогда все в порядке в следующий раз.

Я подумал, может быть, какой-то другой процесс вставлял записи во время моей пакетной программы и одновременно создавал ключи. Однако в таблицах, которые я копирую, не должно быть других пользователей/процессов, пытающихся вставить записи в течение того же периода времени, хотя может происходить ЧТЕНИЕ.

Изменить: добавление информации о создании:

Create table SCHEMA.TABLE1 (
  SYSTEM_USER_KEY   INTEGER   NOT NULL
    generated by default as identity (start with 1  increment by 1  cache 20), 
  COL2...,
)

alter table SCHEMA.TABLE1
    add constraint SYSTEM_USER_SYSTEM_USER_KEY_IDX
    Primary Key (SYSTEM_USER_KEY);

person snowmanjack    schedule 22.11.2013    source источник
comment
Как определяется ваш первичный ключ? Как определяется столбец (столбцы) первичного ключа?   -  person Peter Schuetze    schedule 22.11.2013
comment
@PeterSchuetze - добавлена ​​информация выше.   -  person snowmanjack    schedule 22.11.2013


Ответы (2)


Скорее всего, в вашей таблице есть записи с идентификаторами, которые больше, чем следующее значение в вашей последовательности идентификаторов. Чтобы узнать, каково текущее значение вашей последовательности, выполните следующий запрос.

select s.nextcachefirstvalue-s.cache, s.nextcachefirstvalue-s.increment 
from syscat.COLIDENTATTRIBUTES as a inner join syscat.sequences as s on a.seqid=s.seqid 
where a.tabschema='SCHEMA' 
  and a.TABNAME='TABLE1' 
  and a.COLNAME='SYSTEM_USER_KEY'

Итак, в основном произошло то, что вы каким-то образом получили записи в своей таблице с идентификаторами, которые больше, чем текущее последнее значение вашей последовательности идентификаторов. Поэтому рано или поздно эти идентификаторы столкнутся с идентификаторами, сгенерированными личностью.

Существуют разные причины того, как это могло произойти. Одна из возможностей состоит в том, что были загружены данные, которые уже содержали значения для столбца идентификатора, или были вставлены записи с фактическим значением идентификатора. Другой вариант заключается в том, что последовательность идентификаторов была сброшена, чтобы начинаться с более низкого значения, чем максимальный идентификатор в таблице.

person Peter Schuetze    schedule 22.11.2013
comment
Что мне дает этот запрос? Я получаю 1 строку с 2 столбцами со значениями 8709 и 8728. Должны ли они быть последовательными? В любом случае, я предполагаю, что у меня не должно быть никаких существующих записей с первичным ключом на этих значениях или выше, и я вижу, что у меня действительно есть записи с ключом = 87xx, 88xx и т. д. - person snowmanjack; 23.11.2013
comment
Что мне говорит этот запрос? DB2 не генерирует идентификаторы каждый раз, когда они вам нужны. Он генерирует кучу идентификаторов и выдает их при необходимости. После создания они теряются, когда база данных закрывается, и они еще не использовались. Количество ключей, сгенерированных каждый раз, хранится в столбце cache. Следующий номер, используемый для генерации, хранится в nextcachefirstvalue. Таким образом, запрос сообщает вам первый и последний идентификатор, которые находятся в кеше прямо сейчас и которые будут или были переданы как новые идентификаторы. Я предполагаю, что должен... Верно, вы должны убедиться, что последовательность генерирует идентификаторы выше максимального ключа. - person Peter Schuetze; 25.11.2013
comment
Большое спасибо @Peter-Schuetze! - person snowmanjack; 25.11.2013

Какой бы ни была причина, вам также может понадобиться исправление:

SELECT MAX(<primary_key_column>) FROM onsite.forms;
ALTER TABLE <table> ALTER COLUMN <primary_key_column> RESTART WITH <number from previous query + 1>;
person Edward Anderson    schedule 03.01.2015