Как ограничить таблицу базы данных, чтобы только одна строка могла иметь определенное значение в столбце? - PullRequest
15 голосов
/ 08 октября 2008

Используя Oracle, если значение столбца может быть «ДА» или «НЕТ», возможно ли ограничить таблицу так, чтобы только одна строка могла иметь значение «ДА»?

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

[UDPATE] К сожалению, нулевые значения не допускаются в этой таблице.

Ответы [ 7 ]

19 голосов
/ 08 октября 2008

Использовать индекс на основе функции:

create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);

Oracle индексирует только те ключи, которые не являются полностью нулевыми, и выражение CASE здесь гарантирует, что все значения 'NO' будут заменены на пустые значения и не будут проиндексированы.

6 голосов
/ 08 октября 2008

Это хитрый хак, но если столбец допускает NULL, то вы можете использовать NULL вместо «NO» и «YES», как и раньше. Примените ограничение уникального ключа к этому столбцу, и вы никогда не получите два значения «ДА», но при этом у вас будет много НЕТ.

Обновление: @Nick Pierpoint: предложено добавить проверочное ограничение, чтобы значения столбцов ограничивались только "YES" и NULL. Синтаксис полностью проработан в его ответе.

4 голосов
/ 08 октября 2008

Вы захотите проверить статью Тома Кайта, на которой задается именно этот вопрос, и его ответ:

http://tkyte.blogspot.com/2008/05/another-of-day.html

Резюме: не используйте триггеры, не используйте автономные транзакции, используйте две таблицы.

Если вы используете базу данных Oracle, вы ДОЛЖНЫ узнать AskTom и получить его книги.

3 голосов
/ 08 октября 2008

Не работает с определением таблицы.

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

  1. Установить все строки на "НЕТ"
  2. Установите желаемую строку ДА
2 голосов
/ 08 октября 2008

Исходя из моего комментария к предыдущему ответу 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');
1 голос
/ 08 октября 2008

Поддерживает ли Oracle что-то вроде отфильтрованных индексов (на прошлой неделе я слышал об этом, например, MSSQL2008)? Может быть, вы можете определить уникальный ключ , который применяется только к строкам со значением "Да" в вашем столбце.

0 голосов
/ 08 октября 2008

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

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