2008-10-08 3 views
14

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

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

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

+0

Oh dear - nulls not allowed - это немного изменит ситуацию - теперь вам нужно перейти с функциональным индексом (@Tony Andrews). Все равно избегайте триггеров и автономных транзакций. – 2008-10-09 20:01:20

ответ

19

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

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

Oracle индексирует только ключи, которые не являются полностью пустыми, а выражение СЛУЧАЯ здесь гарантируют, что все значения «нет» заменяются на нули и поэтому не индексируются.

2

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

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

  1. Установить все строки в «NO»
  2. Установите строку, которую вы хотите ДА
+0

-1 для решения на основе триггера. Они никогда не работают хорошо для обеспечения ограничений на уровне таблиц. – 2008-10-08 14:32:31

6

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

Обновление: @Nick Pierpoint: предлагается добавить контрольное ограничение, чтобы значения столбца были ограничены только «ДА» и NULL. Синтаксис разработан в его ответе.

+0

Ничего страшного в этом - это путь.+1 – 2008-10-08 12:17:51

+0

Вам также необходимо добавить ограничение проверки на таблицу, чтобы оно не допускало ничего, кроме «YES» или null. – 2008-10-08 12:21:57

+0

, если вы хотите, чтобы он выглядел красиво, вы, вероятно, могли бы также обернуть просмотр с помощью NVL вокруг него, тогда вы получите свой Y/N – 2008-10-08 13:13:59

1

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

+0

Нет фильтрованных индексов, но ФБР предлагают более гибкий (если возможно, менее краткий) способ сделать то же самое. – orbfish 2011-10-25 16:27:38

-2

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

2

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

Вы хотите проверить статью Tom Kyte с именно этим вопросом спрашивает и его ответ:

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

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

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