16

使用 Oracle,如果列值可以是“YES”或“NO”,是否可以约束表,以便只有一行可以具有“YES”值?

我宁愿重新设计表结构,但这是不可能的。

[UDPATE] 遗憾的是,此表中不允许使用空值。

4

7 回答 7

20

使用基于函数的索引:

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

Oracle 只索引不完全为空的键,这里的 CASE 表达式确保所有“NO”值都更改为空值,因此不被索引。

于 2008-10-08T12:13:33.197 回答
6

这是一个笨拙的 hack,但如果该列允许 NULL,那么您可以使用 NULL 代替“NO”并像以前一样使用“YES”。对该列应用唯一键约束,您将永远不会得到两个“YES”值,但仍然有很多 NO。

更新:@Nick Pierpoint:建议添加一个检查约束,以便将列值限制为“YES”和 NULL。语法都在他的回答中制定出来。

于 2008-10-08T11:42:53.413 回答
4

您将需要查看 Tom Kyte 的文章,其中确切地提出了这个问题和他的答案:

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

总结:不使用触发器,不使用自治事务,使用两张表。

如果您使用 Oracle 数据库,那么您必须了解AskTom并获取他的书籍。

于 2008-10-08T15:25:24.963 回答
3

它不适用于表定义。

但是,如果您使用调用存储过程的触发器更新表,则可以确保只有一行包含“YES”。

  1. 将所有行设置为“否”
  2. 将您想要的行设置为 YES
于 2008-10-08T11:38:17.853 回答
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');
于 2008-10-08T12:30:02.680 回答
1

Oracle 是否支持过滤索引之类的东西(上周我听说例如 MSSQL2008 支持)?也许您可以定义一个唯一键,该键仅适用于列中值为“是”的行。

于 2008-10-08T11:48:40.970 回答
-2

我想我会使用第二个表来指向当前表中的适当行。该其他表也可用于存储其他变量的值。

于 2008-10-08T12:22:40.557 回答