如何约束数据库表,以便只有一行可以在列中具有特定值?

时间:2008-10-08 11:34:53

标签: oracle triggers constraints

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

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

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

7 个答案:

答案 0 :(得分:19)

使用基于函数的索引:

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

Oracle仅索引不完全为null的键,此处的CASE表达式确保所有“NO”值都更改为空,因此不会编入索引。

答案 1 :(得分:6)

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

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

答案 2 :(得分:4)

您将要查看Tom Kyte的文章,正是询问了这个问题及其答案:

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

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

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

答案 3 :(得分:3)

它不适用于表定义。

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

  1. 将所有行设置为“NO”
  2. 将您想要的行设置为是

答案 4 :(得分: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');

答案 5 :(得分:1)

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

答案 6 :(得分:-2)

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