使用 Oracle,如果列值可以是“YES”或“NO”,是否可以约束表,以便只有一行可以具有“YES”值?
我宁愿重新设计表结构,但这是不可能的。
[UDPATE] 遗憾的是,此表中不允许使用空值。
使用 Oracle,如果列值可以是“YES”或“NO”,是否可以约束表,以便只有一行可以具有“YES”值?
我宁愿重新设计表结构,但这是不可能的。
[UDPATE] 遗憾的是,此表中不允许使用空值。
使用基于函数的索引:
create unique index only_one_yes on mytable
(case when col='YES' then 'YES' end);
Oracle 只索引不完全为空的键,这里的 CASE 表达式确保所有“NO”值都更改为空值,因此不被索引。
这是一个笨拙的 hack,但如果该列允许 NULL,那么您可以使用 NULL 代替“NO”并像以前一样使用“YES”。对该列应用唯一键约束,您将永远不会得到两个“YES”值,但仍然有很多 NO。
更新:@Nick Pierpoint:建议添加一个检查约束,以便将列值限制为“YES”和 NULL。语法都在他的回答中制定出来。
您将需要查看 Tom Kyte 的文章,其中确切地提出了这个问题和他的答案:
http://tkyte.blogspot.com/2008/05/another-of-day.html
总结:不使用触发器,不使用自治事务,使用两张表。
如果您使用 Oracle 数据库,那么您必须了解AskTom并获取他的书籍。
它不适用于表定义。
但是,如果您使用调用存储过程的触发器更新表,则可以确保只有一行包含“YES”。
从我的评论到 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');
Oracle 是否支持过滤索引之类的东西(上周我听说例如 MSSQL2008 支持)?也许您可以定义一个唯一键,该键仅适用于列中值为“是”的行。
我想我会使用第二个表来指向当前表中的适当行。该其他表也可用于存储其他变量的值。