Создать ограничение в таблице изменения без проверки существующих данных - PullRequest
5 голосов
/ 03 ноября 2011

Я пытаюсь создать ограничение для таблицы OE.PRODUCT_INFORMATION , поставляемой с Oracle 11g R2. Ограничение должно сделать PRODUCT_NAME уникальным.

Я пробовал это со следующим утверждением:

ALTER TABLE PRODUCT_INFORMATION
  ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME);

Проблема в том, что в OE.PRODUCT_INFORMATION уже есть названия продуктов, которые в настоящее время существуют более двух раз. Выполнение кода выше выдает следующую ошибку:

an alter table validating constraint failed because the table has
duplicate key values.

Существует ли вероятность того, что новое созданное ограничение не будет использоваться для существующих данных таблицы? Я уже пробовал ключевое слово DISABLED. Но когда я включаю ограничение, я получаю то же сообщение об ошибке.

Ответы [ 3 ]

8 голосов
/ 05 мая 2014

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

.
ALTER TABLE PRODUCT_INFORMATION
  ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
  NOVALIDATE;

Если для столбца нет индекса, эта команда создаст неуникальный индекс для столбца.

2 голосов
/ 03 ноября 2011

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

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

http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14251/adfns_triggers.htm

или вы можете просто удалить дублирующиеся значения, а затем применить свое УНИКАЛЬНОЕ ограничение.

РЕДАКТИРОВАТЬ: После комментариев Jonearles и Jeffrey Kemp я добавлю, что вы можете фактически включить уникальное ограничение для таблицы с дублирующимися значениями, используя предложение NOVALIDATE, но вы не сможете иметь уникальный индекс для этот ограниченный столбец.

См. Объяснение Тома Кайта здесь .

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

0 голосов
/ 02 июня 2017

Вы можете использовать отложенный.

ALTER TABLE PRODUCT_INFORMATION
  ADD CONSTRAINT PRINF_NAME_UNIQUE UNIQUE (PRODUCT_NAME)
deferrable initially deferred NOVALIDATE; 
...