Нарушение уникального ограничения во время вставки: почему? (Oracle) - PullRequest
15 голосов
/ 27 сентября 2011

Я пытаюсь создать новую строку в таблице.В таблице есть два ограничения: одно находится в поле ключа (DB_ID), другое ограничивает значение одним из нескольких полей ENV.Когда я делаю вставку, я не включаю поле ключа как одно из полей, которые я пытаюсь вставить, но я получаю эту ошибку:

unique constraint (N390.PK_DB_ID) violated

Вот SQL, который вызывает ошибку:

insert into cmdb_db 
   (narrative_name, db_name, db_type, schema, node, env, server_id, state, path) 
values 
   ('Test Database', 'DB', 'TYPE', 'SCH', '', 'SB01', 381, 'TEST', '')

Единственное, что мне удалось найти, это возможность того, что Oracle может пытаться назначить уже используемый DB_ID, если строки были вставлены вручную.Данные в этой базе данных были каким-то образом восстановлены / перемещены из производственной базы данных, но у меня нет подробной информации о том, как это было сделано.

Есть мысли?

Ответы [ 3 ]

39 голосов
/ 27 сентября 2011

Предположительно, поскольку вы не предоставляете значение для столбца DB_ID, это значение заполняется уровнем строки перед триггером вставки, определенным в таблице.Этот триггер, предположительно, выбирает значение из последовательности.

Поскольку данные были перемещены (предположительно недавно) из производственной базы данных, моя ставка заключалась в том, что при копировании данных последовательность не изменялась какЧто ж.Я предполагаю, что последовательность генерирует значения, которые намного ниже, чем наибольшее значение DB_ID, которое в настоящее время находится в таблице, приводящей к ошибке.

Вы можете подтвердить это подозрение, посмотрев на триггер, чтобы определить, какая последовательностьиспользуется и выполняет

SELECT <<sequence name>>.nextval
  FROM dual

и сравнивает это с

SELECT MAX(db_id)
  FROM cmdb_db

Если, как я подозреваю, последовательность генерирует значения, которые уже существуют в базе данных, вы можете увеличитьпоследовательность до тех пор, пока он не будет генерировать неиспользуемые значения, или вы можете изменить его, чтобы установить INCREMENT во что-то очень большое, получить значение nextval один раз и установить INCREMENT обратно в 1.

1 голос
/ 27 сентября 2011

Ваша ошибка выглядит так, как будто вы дублируете уже существующий первичный ключ в вашей БД.Вы должны изменить свой SQL-код для реализации своего собственного первичного ключа, используя что-то вроде ключевого слова IDENTITY.

CREATE TABLE [DB] (
    [DBId] bigint NOT NULL IDENTITY,
    ...

    CONSTRAINT [DB_PK] PRIMARY KEY ([DB] ASC),

); 
1 голос
/ 27 сентября 2011

Похоже, вы не предоставляете значение для поля первичного ключа DB_ID. Если это первичный ключ, необходимо указать уникальное значение для этого столбца. Единственный способ не предоставить его - создать триггер базы данных, который при вставке предоставил бы значение, наиболее вероятно полученное из последовательности.

Если это восстановление из другой базы данных и существует последовательность в этом новом экземпляре, возможно, он пытается повторно использовать значение. Если у старых данных были уникальные ключи от 1 до 1000, а ваша текущая последовательность равна 500, это будет генерировать значения, которые уже существуют. Если для этой таблицы существует последовательность, и она пытается ее использовать, вам нужно будет согласовать значения в вашей таблице с текущим значением последовательности.

Вы можете использовать SEQUENCE_NAME.CURRVAL, чтобы увидеть текущее значение последовательности (если оно, конечно, существует)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...