Как ограничить таблицу базы данных, так что только одна строка может иметь определенное значение в столбце?
Используя Oracle, если значение столбца может быть "ДА" или "НЕТ", можно ли ограничить таблицу, чтобы только одна строка могла иметь значение "ДА"?
Я бы предпочел перепроектировать структуру таблицы, но это невозможно.
[UDPATE] К сожалению, в этой таблице недопустимые значения не допускаются.
Ответы
Ответ 1
Используйте индекс на основе функций:
create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);
Oracle только индексирует ключи, которые не являются полностью нулевыми, и выражение CASE здесь гарантирует, что все значения "NO" будут изменены на значения NULL и поэтому не индексируются.
Ответ 2
Это кудрявый взлом, но если столбец разрешает NULL, тогда вы можете использовать NULL вместо "НЕТ" и использовать "ДА" так же, как и раньше. Примените уникальное ограничение ключа к этому столбцу, и вы никогда не получите два значения "ДА", но все еще имеете много НЕТ.
Обновление: @Nick Pierpoint: предлагается добавить контрольное ограничение, чтобы значения столбца были ограничены только "YES" и NULL. Синтаксис полностью разработан в его ответе.
Ответ 3
Вы хотите проверить статью Тома Ките именно с этим вопросом и его ответом:
http://tkyte.blogspot.com/2008/05/another-of-day.html
Сводка: не используйте триггеры, не используйте автономные транзакции, используйте две таблицы.
Если вы используете базу данных Oracle, вы ДОЛЖНЫ узнать AskTom и получить его книги.
Ответ 4
Он не работает над определением таблицы.
Однако, если вы обновите таблицу, используя триггер, вызывающий хранимую процедуру, вы можете убедиться, что только одна строка содержит "YES".
- Установите все строки в "НЕТ"
- Задайте строку, в которой вы хотите YES.
Ответ 5
Следуя моему комментарию к предыдущему ответу yukondude, я бы добавил уникальный индекс и контрольное ограничение:
create table mytest (
yesorno varchar2(3 char)
);
create unique index uk_mytest_yesorno on mytest(yesorno);
alter table mytest add constraint ck_mytest_yesorno check (yesorno is null or yesorno = 'YES');
Ответ 6
Поддерживает ли Oracle что-то вроде отфильтрованных индексов (на прошлой неделе я слышал, что, например, MSSQL2008)? Возможно, вы можете определить уникальный ключ, который применяется только к строкам со значением "Да" в вашем столбце.
Ответ 7
Думаю, я бы использовал вторую таблицу, чтобы указать на соответствующую строку в текущей таблице. Эта другая таблица также может использоваться для хранения значений других переменных тоже.